geocoder 1.7.1 → 1.7.4

Sign up to get free protection for your applications and to get access to all the features.
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))