geocoder 1.1.5 → 1.1.6
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.
- data/.travis.yml +4 -0
- data/{CHANGELOG.rdoc → CHANGELOG.md} +90 -37
- data/README.md +96 -45
- data/examples/autoexpire_cache.rb +1 -3
- data/lib/generators/geocoder/config/templates/initializer.rb +18 -22
- data/lib/geocoder.rb +2 -4
- data/lib/geocoder/cache.rb +2 -1
- data/lib/geocoder/calculations.rb +12 -12
- data/lib/geocoder/cli.rb +10 -11
- data/lib/geocoder/configuration.rb +67 -43
- data/lib/geocoder/configuration_hash.rb +11 -0
- data/lib/geocoder/exceptions.rb +3 -0
- data/lib/geocoder/lookup.rb +1 -1
- data/lib/geocoder/lookups/base.rb +59 -16
- data/lib/geocoder/lookups/bing.rb +21 -11
- data/lib/geocoder/lookups/freegeoip.rb +8 -4
- data/lib/geocoder/lookups/geocoder_ca.rb +11 -7
- data/lib/geocoder/lookups/google.rb +18 -9
- data/lib/geocoder/lookups/google_premier.rb +16 -8
- data/lib/geocoder/lookups/mapquest.rb +12 -5
- data/lib/geocoder/lookups/maxmind.rb +72 -0
- data/lib/geocoder/lookups/nominatim.rb +13 -8
- data/lib/geocoder/lookups/test.rb +4 -0
- data/lib/geocoder/lookups/yahoo.rb +38 -11
- data/lib/geocoder/lookups/yandex.rb +17 -9
- data/lib/geocoder/query.rb +17 -8
- data/lib/geocoder/request.rb +7 -1
- data/lib/geocoder/results/google.rb +6 -0
- data/lib/geocoder/results/maxmind.rb +136 -0
- data/lib/geocoder/results/nominatim.rb +0 -10
- data/lib/geocoder/sql.rb +6 -4
- data/lib/geocoder/stores/active_record.rb +5 -5
- data/lib/geocoder/stores/base.rb +3 -2
- data/lib/geocoder/version.rb +1 -1
- data/lib/hash_recursive_merge.rb +74 -0
- data/lib/oauth_util.rb +8 -2
- data/test/cache_test.rb +2 -2
- data/test/calculations_test.rb +4 -4
- data/test/configuration_test.rb +26 -51
- data/test/error_handling_test.rb +4 -4
- data/test/fixtures/bing_invalid_key +1 -0
- data/test/fixtures/{bing_madison_square_garden.json → bing_madison_square_garden} +0 -0
- data/test/fixtures/{bing_no_results.json → bing_no_results} +0 -0
- data/test/fixtures/{bing_reverse.json → bing_reverse} +0 -0
- data/test/fixtures/{freegeoip_74_200_247_59.json → freegeoip_74_200_247_59} +0 -0
- data/test/fixtures/{freegeoip_no_results.json → freegeoip_no_results} +0 -0
- data/test/fixtures/{geocoder_ca_madison_square_garden.json → geocoder_ca_madison_square_garden} +0 -0
- data/test/fixtures/{geocoder_ca_no_results.json → geocoder_ca_no_results} +0 -0
- data/test/fixtures/{geocoder_ca_reverse.json → geocoder_ca_reverse} +0 -0
- data/test/fixtures/{google_garbage.json → google_garbage} +0 -0
- data/test/fixtures/{google_madison_square_garden.json → google_madison_square_garden} +0 -0
- data/test/fixtures/{google_no_city_data.json → google_no_city_data} +0 -0
- data/test/fixtures/{google_no_locality.json → google_no_locality} +0 -0
- data/test/fixtures/{google_no_results.json → google_no_results} +0 -0
- data/test/fixtures/{mapquest_madison_square_garden.json → mapquest_madison_square_garden} +0 -0
- data/test/fixtures/{mapquest_no_results.json → mapquest_no_results} +0 -0
- data/test/fixtures/maxmind_24_24_24_21 +1 -0
- data/test/fixtures/maxmind_24_24_24_22 +1 -0
- data/test/fixtures/maxmind_24_24_24_23 +1 -0
- data/test/fixtures/maxmind_24_24_24_24 +1 -0
- data/test/fixtures/maxmind_74_200_247_59 +1 -0
- data/test/fixtures/maxmind_invalid_key +1 -0
- data/test/fixtures/maxmind_no_results +1 -0
- data/test/fixtures/{nominatim_madison_square_garden.json → nominatim_madison_square_garden} +0 -0
- data/test/fixtures/{nominatim_no_results.json → nominatim_no_results} +0 -0
- data/test/fixtures/{yahoo_error.json → yahoo_error} +0 -0
- data/test/fixtures/yahoo_invalid_key +2 -0
- data/test/fixtures/{yahoo_madison_square_garden.json → yahoo_madison_square_garden} +0 -0
- data/test/fixtures/{yahoo_no_results.json → yahoo_no_results} +0 -0
- data/test/fixtures/yahoo_over_limit +2 -0
- data/test/fixtures/{yandex_invalid_key.json → yandex_invalid_key} +0 -0
- data/test/fixtures/{yandex_kremlin.json → yandex_kremlin} +0 -0
- data/test/fixtures/{yandex_no_results.json → yandex_no_results} +0 -0
- data/test/https_test.rb +3 -3
- data/test/integration/smoke_test.rb +2 -2
- data/test/lookup_test.rb +82 -5
- data/test/oauth_util_test.rb +30 -0
- data/test/proxy_test.rb +2 -2
- data/test/query_test.rb +3 -0
- data/test/result_test.rb +2 -2
- data/test/services_test.rb +121 -44
- data/test/test_helper.rb +44 -109
- data/test/test_mode_test.rb +3 -3
- metadata +42 -33
@@ -4,16 +4,28 @@ require "geocoder/results/yandex"
|
|
4
4
|
module Geocoder::Lookup
|
5
5
|
class Yandex < Base
|
6
6
|
|
7
|
+
def name
|
8
|
+
"Yandex"
|
9
|
+
end
|
10
|
+
|
7
11
|
def map_link_url(coordinates)
|
8
12
|
"http://maps.yandex.ru/?ll=#{coordinates.reverse.join(',')}"
|
9
13
|
end
|
10
14
|
|
15
|
+
def query_url(query)
|
16
|
+
"#{protocol}://geocode-maps.yandex.ru/1.x/?" + url_query_string(query)
|
17
|
+
end
|
18
|
+
|
11
19
|
private # ---------------------------------------------------------------
|
12
20
|
|
13
21
|
def results(query)
|
14
22
|
return [] unless doc = fetch_data(query)
|
15
23
|
if err = doc['error']
|
16
|
-
|
24
|
+
if err["status"] == 401 and err["message"] == "invalid key"
|
25
|
+
raise_error(Geocoder::InvalidApiKey) || warn("Invalid API key.")
|
26
|
+
else
|
27
|
+
warn "Yandex Geocoding API error: #{err['status']} (#{err['message']})."
|
28
|
+
end
|
17
29
|
return []
|
18
30
|
end
|
19
31
|
if doc = doc['response']['GeoObjectCollection']
|
@@ -31,16 +43,12 @@ module Geocoder::Lookup
|
|
31
43
|
else
|
32
44
|
q = query.sanitized_text
|
33
45
|
end
|
34
|
-
|
46
|
+
{
|
35
47
|
:geocode => q,
|
36
48
|
:format => "json",
|
37
|
-
:plng => "#{
|
38
|
-
:key =>
|
39
|
-
)
|
40
|
-
end
|
41
|
-
|
42
|
-
def query_url(query)
|
43
|
-
"#{protocol}://geocode-maps.yandex.ru/1.x/?" + url_query_string(query)
|
49
|
+
:plng => "#{configuration.language}", # supports ru, uk, be
|
50
|
+
:key => configuration.api_key
|
51
|
+
}.merge(super)
|
44
52
|
end
|
45
53
|
end
|
46
54
|
end
|
data/lib/geocoder/query.rb
CHANGED
@@ -36,17 +36,20 @@ module Geocoder
|
|
36
36
|
Lookup.get(name)
|
37
37
|
end
|
38
38
|
|
39
|
+
def url
|
40
|
+
lookup.query_url(self)
|
41
|
+
end
|
42
|
+
|
39
43
|
##
|
40
|
-
# Is the Query
|
44
|
+
# Is the Query blank? (ie, should we not bother searching?)
|
45
|
+
# A query is considered blank if its text is nil or empty string AND
|
46
|
+
# no URL parameters are specified.
|
41
47
|
#
|
42
48
|
def blank?
|
43
|
-
|
44
|
-
|
45
|
-
text.
|
46
|
-
|
47
|
-
else
|
48
|
-
!!text.to_s.match(/^\s*$/)
|
49
|
-
end
|
49
|
+
!params_given? and (
|
50
|
+
(text.is_a?(Array) and text.compact.size < 2) or
|
51
|
+
text.to_s.match(/^\s*$/)
|
52
|
+
)
|
50
53
|
end
|
51
54
|
|
52
55
|
##
|
@@ -90,5 +93,11 @@ module Geocoder
|
|
90
93
|
def reverse_geocode?
|
91
94
|
coordinates?
|
92
95
|
end
|
96
|
+
|
97
|
+
private # ----------------------------------------------------------------
|
98
|
+
|
99
|
+
def params_given?
|
100
|
+
!!(options[:params].is_a?(Hash) and options[:params].keys.size > 0)
|
101
|
+
end
|
93
102
|
end
|
94
103
|
end
|
data/lib/geocoder/request.rb
CHANGED
@@ -5,7 +5,13 @@ module Geocoder
|
|
5
5
|
|
6
6
|
def location
|
7
7
|
unless defined?(@location)
|
8
|
-
|
8
|
+
if env.has_key?('HTTP_X_REAL_IP')
|
9
|
+
@location = Geocoder.search(env['HTTP_X_REAL_IP']).first
|
10
|
+
elsif env.has_key?('HTTP_X_FORWARDED_FOR')
|
11
|
+
@location = Geocoder.search(env['HTTP_X_FORWARDED_FOR']).first
|
12
|
+
else
|
13
|
+
@location = Geocoder.search(ip).first
|
14
|
+
end
|
9
15
|
end
|
10
16
|
@location
|
11
17
|
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'geocoder/results/base'
|
2
|
+
|
3
|
+
module Geocoder::Result
|
4
|
+
class Maxmind < Base
|
5
|
+
|
6
|
+
##
|
7
|
+
# Hash mapping service names to names of returned fields.
|
8
|
+
#
|
9
|
+
def self.field_names
|
10
|
+
{
|
11
|
+
:country => [
|
12
|
+
:country_code,
|
13
|
+
:error
|
14
|
+
],
|
15
|
+
|
16
|
+
:city => [
|
17
|
+
:country_code,
|
18
|
+
:region_code,
|
19
|
+
:city_name,
|
20
|
+
:latitude,
|
21
|
+
:longitude,
|
22
|
+
:error
|
23
|
+
],
|
24
|
+
|
25
|
+
:city_isp_org => [
|
26
|
+
:country_code,
|
27
|
+
:region_code,
|
28
|
+
:city_name,
|
29
|
+
:postal_code,
|
30
|
+
:latitude,
|
31
|
+
:longitude,
|
32
|
+
:metro_code,
|
33
|
+
:area_code,
|
34
|
+
:isp_name,
|
35
|
+
:organization_name,
|
36
|
+
:error
|
37
|
+
],
|
38
|
+
|
39
|
+
:omni => [
|
40
|
+
:country_code,
|
41
|
+
:country_name,
|
42
|
+
:region_code,
|
43
|
+
:region_name,
|
44
|
+
:city_name,
|
45
|
+
:latitude,
|
46
|
+
:longitude,
|
47
|
+
:metro_code,
|
48
|
+
:area_code,
|
49
|
+
:time_zone,
|
50
|
+
:continent_code,
|
51
|
+
:postal_code,
|
52
|
+
:isp_name,
|
53
|
+
:organization_name,
|
54
|
+
:domain,
|
55
|
+
:as_number,
|
56
|
+
:netspeed,
|
57
|
+
:user_type,
|
58
|
+
:accuracy_radius,
|
59
|
+
:country_confidence_factor,
|
60
|
+
:city_confidence_factor,
|
61
|
+
:region_confidence_factor,
|
62
|
+
:postal_confidence_factor,
|
63
|
+
:error
|
64
|
+
]
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Name of the MaxMind service being used.
|
70
|
+
# Inferred from format of @data.
|
71
|
+
#
|
72
|
+
def service_name
|
73
|
+
self.class.field_names.to_a.each do |n,f|
|
74
|
+
return n if f.size == @data.size
|
75
|
+
end
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
|
79
|
+
def field_names
|
80
|
+
self.class.field_names[service_name]
|
81
|
+
end
|
82
|
+
|
83
|
+
def data_hash
|
84
|
+
@data_hash ||= Hash[*field_names.zip(@data).flatten]
|
85
|
+
end
|
86
|
+
|
87
|
+
def coordinates
|
88
|
+
[data_hash[:latitude].to_f, data_hash[:longitude].to_f]
|
89
|
+
end
|
90
|
+
|
91
|
+
def address(format = :full)
|
92
|
+
s = state_code.to_s == "" ? "" : ", #{state_code}"
|
93
|
+
"#{city}#{s} #{postal_code}, #{country_code}".sub(/^[ ,]*/, "")
|
94
|
+
end
|
95
|
+
|
96
|
+
def city
|
97
|
+
data_hash[:city_name]
|
98
|
+
end
|
99
|
+
|
100
|
+
def state # not given by MaxMind
|
101
|
+
data_hash[:region_name] || data_hash[:region_code]
|
102
|
+
end
|
103
|
+
|
104
|
+
def state_code
|
105
|
+
data_hash[:region_code]
|
106
|
+
end
|
107
|
+
|
108
|
+
def country #not given by MaxMind
|
109
|
+
data_hash[:country_name] || data_hash[:country_code]
|
110
|
+
end
|
111
|
+
|
112
|
+
def country_code
|
113
|
+
data_hash[:country_code]
|
114
|
+
end
|
115
|
+
|
116
|
+
def postal_code
|
117
|
+
data_hash[:postal_code]
|
118
|
+
end
|
119
|
+
|
120
|
+
def method_missing(method, *args, &block)
|
121
|
+
if field_names.include?(method)
|
122
|
+
data_hash[method]
|
123
|
+
else
|
124
|
+
super
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def respond_to?(method)
|
129
|
+
if field_names.include?(method)
|
130
|
+
true
|
131
|
+
else
|
132
|
+
super
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -83,16 +83,6 @@ module Geocoder::Result
|
|
83
83
|
polygonpoints display_name class type stadium]
|
84
84
|
end
|
85
85
|
|
86
|
-
def class
|
87
|
-
warn "DEPRECATION WARNING: The 'class' method of Geocoder::Result::Nominatim objects is deprecated and will be removed in Geocoder version 1.2.0. Please use 'place_class' instead."
|
88
|
-
@data['class']
|
89
|
-
end
|
90
|
-
|
91
|
-
def type
|
92
|
-
warn "DEPRECATION WARNING: The 'type' method of Geocoder::Result::Nominatim objects is deprecated and will be removed in Geocoder version 1.2.0. Please use 'place_type' instead."
|
93
|
-
@data['type']
|
94
|
-
end
|
95
|
-
|
96
86
|
response_attributes.each do |a|
|
97
87
|
unless method_defined?(a)
|
98
88
|
define_method a do
|
data/lib/geocoder/sql.rb
CHANGED
@@ -11,7 +11,8 @@ module Geocoder
|
|
11
11
|
# http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
|
12
12
|
#
|
13
13
|
def full_distance(latitude, longitude, lat_attr, lon_attr, options = {})
|
14
|
-
|
14
|
+
units = options[:units] || Geocoder.config.units
|
15
|
+
earth = Geocoder::Calculations.earth_radius(units)
|
15
16
|
|
16
17
|
"#{earth} * 2 * ASIN(SQRT(" +
|
17
18
|
"POWER(SIN((#{latitude.to_f} - #{lat_attr}) * PI() / 180 / 2), 2) + " +
|
@@ -31,8 +32,9 @@ module Geocoder
|
|
31
32
|
# are not intended for use in production!
|
32
33
|
#
|
33
34
|
def approx_distance(latitude, longitude, lat_attr, lon_attr, options = {})
|
34
|
-
|
35
|
-
|
35
|
+
units = options[:units] || Geocoder.config.units
|
36
|
+
dx = Geocoder::Calculations.longitude_degree_distance(30, units)
|
37
|
+
dy = Geocoder::Calculations.latitude_degree_distance(units)
|
36
38
|
|
37
39
|
# sin of 45 degrees = average x or y component of vector
|
38
40
|
factor = Math.sin(Math::PI / 4)
|
@@ -61,7 +63,7 @@ module Geocoder
|
|
61
63
|
# http://www.beginningspatial.com/calculating_bearing_one_point_another
|
62
64
|
#
|
63
65
|
def full_bearing(latitude, longitude, lat_attr, lon_attr, options = {})
|
64
|
-
case options[:bearing]
|
66
|
+
case options[:bearing] || Geocoder.config.distances
|
65
67
|
when :linear
|
66
68
|
"CAST(" +
|
67
69
|
"DEGREES(ATAN2( " +
|
@@ -87,19 +87,19 @@ module Geocoder::Store
|
|
87
87
|
# * +:units+ - <tt>:mi</tt> or <tt>:km</tt>; to be used.
|
88
88
|
# for interpreting radius as well as the +distance+ attribute which
|
89
89
|
# is added to each found nearby object.
|
90
|
-
#
|
90
|
+
# Use Geocoder.configure[:units] to configure default units.
|
91
91
|
# * +:bearing+ - <tt>:linear</tt> or <tt>:spherical</tt>.
|
92
92
|
# the method to be used for calculating the bearing (direction)
|
93
93
|
# between the given point and each found nearby point;
|
94
|
-
# set to false for no bearing calculation.
|
95
|
-
#
|
94
|
+
# set to false for no bearing calculation. Use
|
95
|
+
# Geocoder.configure[:distances] to configure default calculation method.
|
96
96
|
# * +:select+ - string with the SELECT SQL fragment (e.g. “id, name”)
|
97
97
|
# * +:order+ - column(s) for ORDER BY SQL clause; default is distance;
|
98
98
|
# set to false or nil to omit the ORDER BY clause
|
99
99
|
# * +:exclude+ - an object to exclude (used by the +nearbys+ method)
|
100
100
|
#
|
101
101
|
def near_scope_options(latitude, longitude, radius = 20, options = {})
|
102
|
-
options[:units] ||= (geocoder_options[:units] || Geocoder
|
102
|
+
options[:units] ||= (geocoder_options[:units] || Geocoder.config.units)
|
103
103
|
bearing = bearing_sql(latitude, longitude, options)
|
104
104
|
distance = distance_sql(latitude, longitude, options)
|
105
105
|
|
@@ -143,7 +143,7 @@ module Geocoder::Store
|
|
143
143
|
#
|
144
144
|
def bearing_sql(latitude, longitude, options = {})
|
145
145
|
if !options.include?(:bearing)
|
146
|
-
options[:bearing] = Geocoder
|
146
|
+
options[:bearing] = Geocoder.config.distances
|
147
147
|
end
|
148
148
|
if options[:bearing]
|
149
149
|
method_prefix = using_sqlite? ? "approx" : "full"
|
data/lib/geocoder/stores/base.rb
CHANGED
@@ -58,10 +58,11 @@ module Geocoder
|
|
58
58
|
##
|
59
59
|
# Get nearby geocoded objects.
|
60
60
|
# Takes the same options hash as the near class method (scope).
|
61
|
+
# Returns nil if the object is not geocoded.
|
61
62
|
#
|
62
63
|
def nearbys(radius = 20, options = {})
|
63
|
-
return
|
64
|
-
options.merge!(:exclude => self)
|
64
|
+
return nil unless geocoded?
|
65
|
+
options.merge!(:exclude => self) unless send(self.class.primary_key).nil?
|
65
66
|
self.class.near(self, radius, options)
|
66
67
|
end
|
67
68
|
|
data/lib/geocoder/version.rb
CHANGED
@@ -0,0 +1,74 @@
|
|
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
CHANGED
@@ -3,6 +3,13 @@
|
|
3
3
|
# Source: http://gist.github.com/383159
|
4
4
|
# License: http://gist.github.com/375593
|
5
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
|
+
#
|
6
13
|
|
7
14
|
require 'uri'
|
8
15
|
require 'cgi'
|
@@ -56,7 +63,7 @@ class OauthUtil
|
|
56
63
|
def query_string
|
57
64
|
pairs = []
|
58
65
|
@params.sort.each { | key, val |
|
59
|
-
pairs.push( "#{
|
66
|
+
pairs.push( "#{ CGI.escape(key.to_s).gsub(/%(5B|5D)/n) { [$1].pack('H*') } }=#{ CGI.escape(val.to_s) }" )
|
60
67
|
}
|
61
68
|
pairs.join '&'
|
62
69
|
end
|
@@ -74,7 +81,6 @@ class OauthUtil
|
|
74
81
|
|
75
82
|
# if url has query, merge key/values into params obj overwriting defaults
|
76
83
|
if parsed_url.query
|
77
|
-
#@params.merge! CGI.parse( parsed_url.query )
|
78
84
|
CGI.parse( parsed_url.query ).each do |k,v|
|
79
85
|
if v.is_a?(Array) && v.count == 1
|
80
86
|
@params[k] = v.first
|