Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control Google places search API price #1461

Merged
merged 2 commits into from
Aug 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions lib/geocoder/lookups/google.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,15 @@ def valid_response?(response)
super(response) and ['OK', 'ZERO_RESULTS'].include?(status)
end

def result_root_attr
'results'
end

def results(query)
return [] unless doc = fetch_data(query)
case doc['status']; when "OK" # OK status implies >0 results
return doc['results']
case doc['status']
when "OK" # OK status implies >0 results
return doc[result_root_attr]
when "OVER_QUERY_LIMIT"
raise_error(Geocoder::OverQueryLimitError) ||
Geocoder.log(:warn, "#{name} API error: over query limit.")
Expand Down
22 changes: 8 additions & 14 deletions lib/geocoder/lookups/google_places_details.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,15 @@ def base_query_url(query)
"#{protocol}://maps.googleapis.com/maps/api/place/details/json?"
end

def result_root_attr
'result'
end

def results(query)
return [] unless doc = fetch_data(query)

case doc["status"]
when "OK"
return [doc["result"]]
when "OVER_QUERY_LIMIT"
raise_error(Geocoder::OverQueryLimitError) || Geocoder.log(:warn, "Google Places Details API error: over query limit.")
when "REQUEST_DENIED"
raise_error(Geocoder::RequestDenied) || Geocoder.log(:warn, "Google Places Details API error: request denied.")
when "INVALID_REQUEST"
raise_error(Geocoder::InvalidRequest) || Geocoder.log(:warn, "Google Places Details API error: invalid request.")
end

[]
result = super(query)
return [result] unless result.is_a? Array

result
end

def query_url_google_params(query)
Expand Down
30 changes: 28 additions & 2 deletions lib/geocoder/lookups/google_places_search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,42 @@ def supported_protocols

private

def result_root_attr
'candidates'
end

def base_query_url(query)
"#{protocol}://maps.googleapis.com/maps/api/place/textsearch/json?"
"#{protocol}://maps.googleapis.com/maps/api/place/findplacefromtext/json?"
end

def query_url_google_params(query)
{
query: query.text,
input: query.text,
inputtype: 'textquery',
fields: fields(query),
language: query.language || configuration.language
}
end

def fields(query)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By default every fields are requested, to prevent any regression from developers already using the gem.

query_fields = query.options[:fields]
return format_fields(query_fields) if query_fields

default_fields
end

def default_fields
legacy = %w[id reference]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

id and reference fields were already available in the previous API response (Text search response), I added those 2 fields here to prevent any regression for developers already using the gem

basic = %w[business_status formatted_address geometry icon name
photos place_id plus_code types]
contact = %w[opening_hours]
atmosphere = %W[price_level rating user_ratings_total]
format_fields(legacy, basic, contact, atmosphere)
end

def format_fields(*fields)
fields.flatten.join(',')
end
end
end
end
4 changes: 4 additions & 0 deletions lib/geocoder/lookups/google_premier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ def query_url(query)

private # ---------------------------------------------------------------

def result_root_attr
'results'
end

def cache_key(query)
"#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + hash_to_query(cache_key_params(query))
end
Expand Down
3 changes: 1 addition & 2 deletions test/fixtures/google_places_search_madison_square_garden
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"html_attributions" : [],
"results" : [
"candidates" : [
{
"formatted_address" : "4 Pennsylvania Plaza, New York, NY 10001, United States",
"geometry" : {
Expand Down
32 changes: 31 additions & 1 deletion test/unit/lookups/google_places_search_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,39 @@ def test_google_places_search_query_url_contains_language
assert_match(/language=de/, url)
end

def test_google_places_search_query_url_contains_input
url = lookup.query_url(Geocoder::Query.new("some-address"))
assert_match(/input=some-address/, url)
end

def test_google_places_search_query_url_contains_input_typer
url = lookup.query_url(Geocoder::Query.new("some-address"))
assert_match(/inputtype=textquery/, url)
end

def test_google_places_search_query_url_always_uses_https
url = lookup.query_url(Geocoder::Query.new("some-address"))
assert_match(%r(^https://), url)
assert_match(%r{^https://}, url)
end

def test_google_places_search_query_url_contains_every_field_available_by_default
url = lookup.query_url(Geocoder::Query.new("some-address"))
fields = %w[id reference business_status formatted_address geometry icon name
photos place_id plus_code types opening_hours price_level rating
user_ratings_total]
assert_match(/fields=#{fields.join('%2C')}/, url)
end

def test_google_places_search_query_url_contains_specific_fields_when_given
fields = %w[formatted_address place_id]
url = lookup.query_url(Geocoder::Query.new("some-address", fields: fields))

assert_match(/fields=#{fields.join('%2C')}/, url)
end

def test_google_places_search_query_url_uses_find_place_service
url = lookup.query_url(Geocoder::Query.new("some-address"))
assert_match(%r{//maps.googleapis.com/maps/api/place/findplacefromtext/}, url)
end

private
Expand Down