geocoder 1.7.1 → 1.7.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29b831bd2fcb54be9ffadc479be5c2010fb11191b1f240e0868d8ff6bdd379af
4
- data.tar.gz: 0d9ca932a2cdcd36b0014e271a96afbc867f6b0f151b1e119c533d64b260048e
3
+ metadata.gz: e298d39c596857e28539779ed539ad5f9995368f3021f6541deb53d478b80a0a
4
+ data.tar.gz: ed9831a260f47cba9d9bc9a069c6e04362621e3cb72175c56332973196420679
5
5
  SHA512:
6
- metadata.gz: aa027cbdf72f35e4c19e9413f483c245a7a8b1286ac5ad9cc9c527fd8d05e9ab4dd6a43065a60dac089ec94e2798228f823a2d517d8b0b36ef0c978a9bc59cd6
7
- data.tar.gz: 20e927de754e571eb2587734a2027e5aeb57bb8a38a487b6a8d04504bb6b22678b4ab2c9485e0a79d0006969468254a8c094e543192a0f305b62346adb129c43
6
+ metadata.gz: a7801cdd189f6ae89c512b42ce57d4a34a37a0750596f2df4f299693be2318ab2e3d0f55970ec0f9f14435c05d86c56bb3989f28748f972aa8d8fc9409adf927
7
+ data.tar.gz: cc35bb7280bcb43bb9c082dfac6ca5dc395fe3690080d809054761cf147a943868d05ce4f8ce9e4a31b2c67e019e483abcb7c114c7ca711b9c9961e523e57425
data/CHANGELOG.md CHANGED
@@ -3,6 +3,19 @@ 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.7.4 (2022 Mar 14)
7
+ -------------------
8
+ * Add ability to use app-defined lookups (thanks github.com/januszm).
9
+ * Updates to LocationIQ and FreeGeoIP lookups.
10
+
11
+ 1.7.3 (2022 Jan 17)
12
+ -------------------
13
+ * Get rid of unnecessary cache_prefix deprecation warnings.
14
+
15
+ 1.7.2 (2022 Jan 2)
16
+ -------------------
17
+ * Fix uninitialized constant error (occurring on some systems with v1.7.1).
18
+
6
19
  1.7.1 (2022 Jan 1)
7
20
  -------------------
8
21
  * Various bugfixes and refactorings.
data/README.md CHANGED
@@ -20,7 +20,7 @@ Compatibility:
20
20
 
21
21
  * Ruby versions: 2.1+, and JRuby.
22
22
  * Databases: MySQL, PostgreSQL, SQLite, and MongoDB.
23
- * Rails: 5.x and 6.x.
23
+ * Rails: 5.x, 6.x, and 7.x.
24
24
  * Works outside of Rails with the `json` (for MRI) or `json_pure` (for JRuby) gem.
25
25
 
26
26
 
@@ -78,7 +78,7 @@ results.first.address
78
78
  # => "Hôtel de Ville, 75004 Paris, France"
79
79
  ```
80
80
 
81
- You can also look up the location of an IP addresses:
81
+ You can also look up the location of an IP address:
82
82
 
83
83
  ```ruby
84
84
  results = Geocoder.search("172.56.21.89")
@@ -350,10 +350,16 @@ This example uses Redis, but the cache store can be any object that supports the
350
350
 
351
351
  Even a plain Ruby hash will work, though it's not a great choice (cleared out when app is restarted, not shared between app instances, etc).
352
352
 
353
+ When using Rails use the Generic cache store as an adapter around `Rails.cache`:
354
+
355
+ ```ruby
356
+ Geocoder.configure(cache: Geocoder::CacheStore::Generic.new(Rails.cache, {}))
357
+ ```
358
+
353
359
  You can also set a custom prefix to be used for cache keys:
354
360
 
355
361
  ```ruby
356
- Geocoder.configure(cache_prefix: "...")
362
+ Geocoder.configure(cache_options: { prefix: "..." })
357
363
  ```
358
364
 
359
365
  By default the prefix is `geocoder:`
@@ -0,0 +1,22 @@
1
+ # To extend the Geocoder with additional lookups that come from the application,
2
+ # not shipped with the gem, define a "child" lookup in your application, based on existing one.
3
+ # This is required because the Geocoder::Configuration is a Singleton and stores one api key per lookup.
4
+
5
+ # in app/libs/geocoder/lookup/my_preciousss.rb
6
+ module Geocoder::Lookup
7
+ class MyPreciousss < Google
8
+ end
9
+ end
10
+
11
+ # Update Geocoder's street_services on initialize:
12
+ # config/initializers/geocoder.rb
13
+ Geocoder::Lookup.street_services << :my_preciousss
14
+
15
+ # Override the configuration when necessary (e.g. provide separate Google API key for the account):
16
+ Geocoder.configure(my_preciousss: { api_key: 'abcdef' })
17
+
18
+ # Lastly, search using your custom lookup service/api keys
19
+ Geocoder.search("Paris", lookup: :my_preciousss)
20
+
21
+ # This is useful when we have groups of users in the application who use Google paid services
22
+ # and we want to properly separate them and allow using individual API KEYS or timeouts.
@@ -1,3 +1,5 @@
1
+ require 'geocoder/cache_stores/base'
2
+
1
3
  module Geocoder::CacheStore
2
4
  class Generic < Base
3
5
  def write(url, value)
@@ -30,4 +32,4 @@ module Geocoder::CacheStore
30
32
  store.delete(key)
31
33
  end
32
34
  end
33
- end
35
+ end
@@ -1,3 +1,5 @@
1
+ require 'geocoder/cache_stores/base'
2
+
1
3
  module Geocoder::CacheStore
2
4
  class Redis < Base
3
5
  def initialize(store, options)
@@ -29,4 +31,4 @@ module Geocoder::CacheStore
29
31
 
30
32
  def expire; @expiration; end
31
33
  end
32
- end
34
+ end
@@ -108,8 +108,8 @@ module Geocoder
108
108
  @data[:http_proxy] = nil # HTTP proxy server (user:pass@host:port)
109
109
  @data[:https_proxy] = nil # HTTPS proxy server (user:pass@host:port)
110
110
  @data[:api_key] = nil # API key for geocoding service
111
- @data[:cache] = nil # cache object (must respond to #[], #[]=, and #keys)
112
- @data[:cache_prefix] = "geocoder:" # - DEPRECATED - prefix (string) to use for all cache keys
111
+ @data[:cache] = nil # cache object (must respond to #[], #[]=, and optionally #keys)
112
+ @data[:cache_prefix] = nil # - DEPRECATED - prefix (string) to use for all cache keys
113
113
  @data[:basic_auth] = {} # user and password for basic auth ({:user => "user", :password => "password"})
114
114
  @data[:logger] = :kernel # :kernel or Logger instance
115
115
  @data[:kernel_logger_level] = ::Logger::WARN # log level, if kernel logger is used
@@ -124,7 +124,8 @@ module Geocoder
124
124
  @data[:distances] = :linear # :linear or :spherical
125
125
 
126
126
  # explicit cache service options
127
- @data[:cache_options] = {}
127
+ @data[:cache_options] ||= {}
128
+ @data[:cache_options][:prefix] = "geocoder:"
128
129
  end
129
130
 
130
131
  instance_eval(OPTIONS.map do |option|
@@ -117,8 +117,7 @@ module Geocoder
117
117
  def spawn(name)
118
118
  if all_services.include?(name)
119
119
  name = name.to_s
120
- require "geocoder/lookups/#{name}"
121
- Geocoder::Lookup.const_get(classify_name(name)).new
120
+ instantiate_lookup(name)
122
121
  else
123
122
  valids = all_services.map(&:inspect).join(", ")
124
123
  raise ConfigurationError, "Please specify a valid lookup for Geocoder " +
@@ -132,5 +131,18 @@ module Geocoder
132
131
  def classify_name(filename)
133
132
  filename.to_s.split("_").map{ |i| i[0...1].upcase + i[1..-1] }.join
134
133
  end
134
+
135
+ ##
136
+ # Safely instantiate Lookup
137
+ #
138
+ def instantiate_lookup(name)
139
+ class_name = classify_name(name)
140
+ begin
141
+ Geocoder::Lookup.const_get(class_name)
142
+ rescue NameError
143
+ require "geocoder/lookups/#{name}"
144
+ end
145
+ Geocoder::Lookup.const_get(class_name).new
146
+ end
135
147
  end
136
148
  end
@@ -17,14 +17,16 @@ module Geocoder::Lookup
17
17
  end
18
18
  end
19
19
 
20
- def query_url(query)
21
- "#{protocol}://#{host}/json/#{query.sanitized_text}"
22
- end
23
-
24
20
  private # ---------------------------------------------------------------
25
21
 
26
- def cache_key(query)
27
- query_url(query)
22
+ def base_query_url(query)
23
+ "#{protocol}://#{host}/json/#{query.sanitized_text}?"
24
+ end
25
+
26
+ def query_url_params(query)
27
+ {
28
+ :apikey => configuration.api_key
29
+ }.merge(super)
28
30
  end
29
31
 
30
32
  def parse_raw_data(raw_data)
@@ -11,6 +11,10 @@ module Geocoder::Lookup
11
11
  ["api_key"]
12
12
  end
13
13
 
14
+ def supported_protocols
15
+ [:https]
16
+ end
17
+
14
18
  private # ----------------------------------------------------------------
15
19
 
16
20
  def base_query_url(query)
@@ -25,7 +29,7 @@ module Geocoder::Lookup
25
29
  end
26
30
 
27
31
  def configured_host
28
- configuration[:host] || "locationiq.org"
32
+ configuration[:host] || "us1.locationiq.com"
29
33
  end
30
34
 
31
35
  def results(query)
@@ -4,12 +4,12 @@ module Geocoder::Result
4
4
  class Nominatim < Base
5
5
 
6
6
  def poi
7
- return @data['address'][place_type] if @data['address'].key?(place_type)
7
+ return address_data[place_type] if address_data.key?(place_type)
8
8
  return nil
9
9
  end
10
10
 
11
11
  def house_number
12
- @data['address']['house_number']
12
+ address_data['house_number']
13
13
  end
14
14
 
15
15
  def address
@@ -18,69 +18,71 @@ module Geocoder::Result
18
18
 
19
19
  def street
20
20
  %w[road pedestrian highway].each do |key|
21
- return @data['address'][key] if @data['address'].key?(key)
21
+ return address_data[key] if address_data.key?(key)
22
22
  end
23
23
  return nil
24
24
  end
25
25
 
26
26
  def city
27
27
  %w[city town village hamlet].each do |key|
28
- return @data['address'][key] if @data['address'].key?(key)
28
+ return address_data[key] if address_data.key?(key)
29
29
  end
30
30
  return nil
31
31
  end
32
32
 
33
33
  def village
34
- @data['address']['village']
34
+ address_data['village']
35
35
  end
36
36
 
37
37
  def town
38
- @data['address']['town']
38
+ address_data['town']
39
39
  end
40
40
 
41
41
  def state
42
- @data['address']['state']
42
+ address_data['state']
43
43
  end
44
44
 
45
45
  alias_method :state_code, :state
46
46
 
47
47
  def postal_code
48
- @data['address']['postcode']
48
+ address_data['postcode']
49
49
  end
50
50
 
51
51
  def county
52
- @data['address']['county']
52
+ address_data['county']
53
53
  end
54
54
 
55
55
  def country
56
- @data['address']['country']
56
+ address_data['country']
57
57
  end
58
58
 
59
59
  def country_code
60
- @data['address']['country_code']
60
+ address_data['country_code']
61
61
  end
62
62
 
63
63
  def suburb
64
- @data['address']['suburb']
64
+ address_data['suburb']
65
65
  end
66
66
 
67
67
  def city_district
68
- @data['address']['city_district']
68
+ address_data['city_district']
69
69
  end
70
70
 
71
71
  def state_district
72
- @data['address']['state_district']
72
+ address_data['state_district']
73
73
  end
74
74
 
75
75
  def neighbourhood
76
- @data['address']['neighbourhood']
76
+ address_data['neighbourhood']
77
77
  end
78
78
 
79
79
  def municipality
80
- @data['address']['municipality']
80
+ address_data['municipality']
81
81
  end
82
82
 
83
83
  def coordinates
84
+ return [] unless @data['lat'] && @data['lon']
85
+
84
86
  [@data['lat'].to_f, @data['lon'].to_f]
85
87
  end
86
88
 
@@ -109,5 +111,11 @@ module Geocoder::Result
109
111
  end
110
112
  end
111
113
  end
114
+
115
+ private
116
+
117
+ def address_data
118
+ @data['address'] || {}
119
+ end
112
120
  end
113
121
  end
@@ -1,3 +1,3 @@
1
1
  module Geocoder
2
- VERSION = "1.7.1"
2
+ VERSION = "1.7.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geocoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ version: 1.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Reisner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-01 00:00:00.000000000 Z
11
+ date: 2022-03-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Object geocoding (by street or IP address), reverse geocoding (coordinates
14
14
  to street address), distance queries for ActiveRecord and Mongoid, result caching,
@@ -25,8 +25,7 @@ files:
25
25
  - README.md
26
26
  - bin/console
27
27
  - bin/geocode
28
- - examples/autoexpire_cache_dalli.rb
29
- - examples/autoexpire_cache_redis.rb
28
+ - examples/app_defined_lookup_services.rb
30
29
  - examples/cache_bypass.rb
31
30
  - examples/reverse_geocode_job.rb
32
31
  - lib/easting_northing.rb
@@ -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,30 +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
- # Alternatively, this class could inherit from Redis, which would make most
5
- # of the below methods unnecessary.
6
- class AutoexpireCacheRedis
7
- def initialize(store, ttl = 86400)
8
- @store = store
9
- @ttl = ttl
10
- end
11
-
12
- def [](url)
13
- @store.get(url)
14
- end
15
-
16
- def []=(url, value)
17
- @store.set(url, value)
18
- @store.expire(url, @ttl)
19
- end
20
-
21
- def keys
22
- @store.keys
23
- end
24
-
25
- def del(url)
26
- @store.del(url)
27
- end
28
- end
29
-
30
- Geocoder.configure(:cache => AutoexpireCacheRedis.new(Redis.new))