diff --git a/lib/open_street_map/client.rb b/lib/open_street_map/client.rb index 75fe5e5..4343234 100644 --- a/lib/open_street_map/client.rb +++ b/lib/open_street_map/client.rb @@ -1,10 +1,10 @@ -require 'rest-client' -require 'json' +require 'httparty' require_relative 'client/request' module OpenStreetMap # Client requests class Client + include HTTParty include OpenStreetMap::Client::Request BASE_URI = 'https://nominatim.openstreetmap.org/'.freeze diff --git a/lib/open_street_map/client/request.rb b/lib/open_street_map/client/request.rb index d67d0f4..579b1b8 100644 --- a/lib/open_street_map/client/request.rb +++ b/lib/open_street_map/client/request.rb @@ -4,70 +4,28 @@ class Client module Request private - def call(type, args) - url = generate_url(type, args) - response = fetch(url, args) - parse(response, args[:format]) - rescue - { 'errors' => 'Bad request' } - end - - # generate url from args - def generate_url(type, args) - valid_args_list = valid_args(type) - args = args.select { |key, _value| valid_args_list.include?(key) } - url = args.inject('') { |acc, (key, value)| acc + add_to_options(key, value, acc) } - type + url - end - # make request to API - def fetch(url, args) - url = hostname(args[:hostname]) + url - RestClient.get(url, user_agent: user_agent(args[:user_agent])) + def call(type, args) + url = hostname(args[:hostname]) + type + headers = { 'User-Agent' => user_agent(args[:user_agent]) } + self.class.get(url, query: generate_body(type, args), headers: headers).parsed_response end - # parse response - def parse(response, format) - if json_parse_valid?(format) - JSON.parse(response.body) - else - response.body - end + # generate body from args + def generate_body(type, args) + args['accept-language'.to_sym] = args[:accept_language] if args.key?(:accept_language) + args.select { |key, _| valid_args(type).include?(key) } end # get list of permitted args def valid_args(type) case type - when 'search' then %i[q format addressdetails extratags namedetails viewbox bounded exclude_place_ids limit accept_language email] - when 'reverse' then %i[format lat lon zoom addressdetails extratags namedetails accept_language email] + when 'search' then %i[q format addressdetails extratags namedetails viewbox bounded exclude_place_ids limit accept-language email] + when 'reverse' then %i[format lat lon zoom addressdetails extratags namedetails accept-language email] else [] end end - # make combination of special symbol and param with value - def add_to_options(key, value, acc) - symbol_for_param(acc) + key_value_param(key, remove_spaces(value)) - end - - # select special symbol - def symbol_for_param(acc) - acc == '' ? '?' : '&' - end - - # make combination of param with value - def key_value_param(key, value) - if key == :accept_language - "accept-language=#{value}" - else - "#{key}=#{value}" - end - end - - # replace spaces with + for values - def remove_spaces(value) - value.gsub(/\s+/, '+') - end - # select hostname for request def hostname(value) value || BASE_URI @@ -77,11 +35,6 @@ def hostname(value) def user_agent(value) value || DEFAULT_USER_AGENT end - - # if format equal json then allow parsing - def json_parse_valid?(format) - format == 'json' || format == 'jsonv2' - end end end end diff --git a/open_street_map.gemspec b/open_street_map.gemspec index d160ee7..c13a693 100644 --- a/open_street_map.gemspec +++ b/open_street_map.gemspec @@ -26,5 +26,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'rake', '~> 10.0' spec.add_development_dependency 'rspec', '~> 3.0' spec.add_development_dependency 'rubocop', '~> 0.57.2' - spec.add_dependency 'rest-client', '>= 2.0.2' + spec.add_dependency 'httparty', '~> 0.16' end diff --git a/spec/open_street_map/client/client_spec.rb b/spec/open_street_map/client/client_spec.rb index c851de0..8180729 100644 --- a/spec/open_street_map/client/client_spec.rb +++ b/spec/open_street_map/client/client_spec.rb @@ -21,9 +21,10 @@ end it 'for xml format returns object data' do - response = client.search(q: '135 pilkington avenue, birmingham', format: 'xml', addressdetails: '1') + response = client.search(q: '135 pilkington avenue, birmingham', format: 'xml', addressdetails: '1', accept_language: 'fr') - expect(response.is_a?(String)).to eq true + expect(response.is_a?(Hash)).to eq true + expect(response['searchresults']).to_not eq nil end end end @@ -34,7 +35,7 @@ context 'for bad request' do context 'for bad params' do it 'returns hash with error message' do - expect(client.reverse).to eq('errors' => 'Bad request') + expect(client.reverse).to eq('error' => { 'code' => '400', 'message' => 'Need coordinates or OSM object to lookup.' }) end end end @@ -51,7 +52,8 @@ it 'for xml format returns address data' do response = client.reverse(format: 'xml', lat: rand(47.0..53.0).round(6).to_s, lon: rand(6.0..14.0).round(6).to_s) - expect(response.is_a?(String)).to eq true + expect(response.is_a?(Hash)).to eq true + expect(response['reversegeocode']).to_not eq nil end end end