google-maps 2.2.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.mkd DELETED
@@ -1,39 +0,0 @@
1
- [![Gem Version](https://badge.fury.io/rb/google-maps.svg)](http://badge.fury.io/rb/google-maps)
2
- [![Build Status](https://travis-ci.org/zilverline/google-maps.svg?branch=master)](https://travis-ci.org/zilverline/google-maps)
3
- [![Coverage Status](https://coveralls.io/repos/zilverline/google-maps/badge.svg?branch=master)](https://coveralls.io/r/zilverline/google-maps?branch=master)
4
- [![Code Climate](https://codeclimate.com/repos/55671579695680044d01e0ac/badges/8f4d88f30585847e4fcf/gpa.svg)](https://codeclimate.com/repos/55671579695680044d01e0ac/feed)
5
-
6
- Google Maps
7
- ====================
8
-
9
- Installation
10
- ------------
11
- gem install google-maps
12
-
13
- Usage Examples
14
- --------------
15
- Google::Maps.distance("Science Park, Amsterdam", "Deventer")
16
- #=> "104 km"
17
- Google::Maps.duration("Science Park, Amsterdam", "Deventer")
18
- #=> "1 hour 12 mins"
19
-
20
- route = Google::Maps.route("Science Park, Amsterdam", "Deventer")
21
- route.distance.text
22
- #=> "104 km"
23
- route.duration.text
24
- #=> "1 hour 12 mins"
25
- route.distance.value
26
- #=> 103712
27
- route.duration.value
28
- #=> 4337
29
-
30
- Testing
31
- -------
32
- Run all tests:
33
-
34
- rspec spec/
35
-
36
- Copyright
37
- ---------
38
- Copyright (c) 2011-2014 Zilverline / Daniël van Hoesel.
39
- See [LICENSE](https://github.com/zilverline/google-maps/blob/master/LICENSE.mkd) for details.
@@ -1,44 +0,0 @@
1
- require File.expand_path('../google-maps/configuration', __FILE__)
2
- require File.expand_path('../google-maps/logger', __FILE__)
3
- require File.expand_path('../google-maps/route', __FILE__)
4
- require File.expand_path('../google-maps/place', __FILE__)
5
- require File.expand_path('../google-maps/location', __FILE__)
6
-
7
- module Google
8
- module Maps
9
- extend Configuration
10
- extend Logger
11
-
12
- def self.route(from, to, options={})
13
- Route.new(from, to, options_with_defaults(options))
14
- end
15
-
16
- def self.distance(from, to, options={})
17
- Route.new(from, to, options_with_defaults(options)).distance.text
18
- end
19
-
20
- def self.duration(from, to, options={})
21
- Route.new(from, to, options_with_defaults(options)).duration.text
22
- end
23
-
24
- def self.places(keyword, language = self.default_language)
25
- Place.find(keyword, language)
26
- end
27
-
28
- def self.place(place_id, language = self.default_language)
29
- PlaceDetails.find(place_id, language)
30
- end
31
-
32
- def self.geocode(address, language = self.default_language)
33
- Location.find(address, language)
34
- rescue ZeroResultsException
35
- []
36
- end
37
-
38
- protected
39
-
40
- def self.options_with_defaults(options)
41
- {language: self.default_language}.merge(options)
42
- end
43
- end
44
- end
@@ -1,89 +0,0 @@
1
- # require 'net/http'
2
- require 'httpclient'
3
- require 'uri'
4
- require 'json'
5
- require 'hashie/mash'
6
- require 'base64'
7
- require 'hmac'
8
- require 'hmac-sha1'
9
-
10
- module Google
11
- module Maps
12
-
13
- class InvalidResponseException < StandardError; end
14
- class InvalidPremierConfigurationException < StandardError; end
15
- class ZeroResultsException < InvalidResponseException; end
16
-
17
- class API
18
-
19
- STATUS_OK = "OK".freeze
20
- STATUS_ZERO_RESULTS = "ZERO_RESULTS".freeze
21
-
22
- class << self
23
- def query(service, args = {})
24
- default_args = {sensor: false, use_premier_signing: !Google::Maps.premier_client_id.nil?}
25
- args = default_args.merge(args)
26
- args = args.merge(Google::Maps.default_params[service]) if Google::Maps.default_params[service]
27
- use_premier_signing = args.delete :use_premier_signing
28
- args[:client] = Google::Maps.premier_client_id if use_premier_signing
29
-
30
- url = url(service, args)
31
- url = premier_signing(url) if use_premier_signing
32
- result = Hashie::Mash.new response(url)
33
- raise ZeroResultsException.new("Google did not return any results: #{result.status}") if result.status == STATUS_ZERO_RESULTS
34
- raise InvalidResponseException.new("Google returned an error status: #{result.status}") if result.status != STATUS_OK
35
- result
36
- end
37
-
38
- private
39
-
40
- def decode_url_safe_base_64(value)
41
- Base64.decode64(value.tr('-_','+/'))
42
- end
43
-
44
- def encode_url_safe_base_64(value)
45
- Base64.encode64(value).tr('+/','-_')
46
- end
47
-
48
- def premier_signing(url)
49
- raise InvalidPremierConfigurationException.new("No private key set, set Google::Maps.premier_key") if Google::Maps.premier_key.nil?
50
-
51
- parsed_url = url.is_a?(URI) ? url : URI.parse(url)
52
- url_to_sign = parsed_url.path + '?' + parsed_url.query
53
-
54
- # Decode the private key
55
- raw_key = decode_url_safe_base_64(Google::Maps.premier_key)
56
-
57
- # create a signature using the private key and the URL
58
- sha1 = HMAC::SHA1.new(raw_key)
59
- sha1 << url_to_sign
60
- raw_sig = sha1.digest
61
-
62
- # encode the signature into base64 for url use form.
63
- signature = encode_url_safe_base_64(raw_sig)
64
-
65
- # prepend the server and append the signature.
66
- "#{parsed_url.scheme}://#{parsed_url.host}#{url_to_sign}&signature=#{signature}".strip
67
- end
68
-
69
- def response(url)
70
- JSON.parse(HTTPClient.new.get_content(url))
71
- rescue Exception => error
72
- Google::Maps.logger.error "#{error.message}"
73
- raise InvalidResponseException.new("unknown error: #{error.message}")
74
- end
75
-
76
- def url(service, args = {})
77
- url = URI.parse("#{Google::Maps.end_point}#{Google::Maps.send(service)}/#{Google::Maps.format}#{query_string(args)}")
78
- Google::Maps.logger.debug("url before possible signing: #{url}")
79
- url.to_s
80
- end
81
-
82
- def query_string(args = {})
83
- '?' + args.map { |k,v| "%s=%s" % [URI.encode(k.to_s), URI.encode(v.to_s)] }.join('&') unless args.size <= 0
84
- end
85
- end
86
- end
87
-
88
- end
89
- end
@@ -1,70 +0,0 @@
1
- module Google
2
- module Maps
3
- # Defines constants and methods related to configuration
4
- module Configuration
5
- # An array of valid keys in the options hash when configuring an {Google::Maps::API}
6
- VALID_OPTIONS_KEYS = [:end_point, :premier_key, :premier_client_id, :format, :directions_service, :places_service, :geocode_service, :api_key, :default_language, :place_details_service, :default_params].freeze
7
-
8
- # By default, set "https://maps.googleapis.com/maps/api/" as the server
9
- DEFAULT_END_POINT = "https://maps.googleapis.com/maps/api/".freeze
10
-
11
- DEFAULT_DIRECTIONS_SERVICE = "directions".freeze
12
- DEFAULT_PLACES_SERVICE = "place/autocomplete".freeze
13
- DEFAULT_PLACE_DETAILS_SERVICE = "place/details".freeze
14
- DEFAULT_GEOCODE_SERVICE = "geocode".freeze
15
-
16
- DEFAULT_FORMAT = "json".freeze
17
-
18
- # premier API key to sign parameters
19
- DEFAULT_PREMIER_KEY = nil
20
-
21
- # premier client id
22
- DEFAULT_PREMIER_CLIENT_ID = nil
23
-
24
- # a api key
25
- DEFAULT_API_KEY = nil
26
-
27
- # default language
28
- DEFAULT_LANGUAGE = :en
29
-
30
- # params to send which each request configured per service, ie.: {places_service: {location: "52.0910,5.1220", radius: 300000}}
31
- DEFAULT_PARAMS = {}
32
-
33
- # @private
34
- attr_accessor *VALID_OPTIONS_KEYS
35
-
36
- # When this module is extended, set all configuration options to their default values
37
- def self.extended(base)
38
- base.reset
39
- end
40
-
41
- # Convenience method to allow configuration options to be set in a block
42
- def configure
43
- yield self
44
- end
45
-
46
- # Create a hash of options and their values
47
- def options
48
- VALID_OPTIONS_KEYS.inject({}) do |option, key|
49
- option.merge!(key => send(key))
50
- end
51
- end
52
-
53
- # Reset all configuration options to defaults
54
- def reset
55
- self.end_point = DEFAULT_END_POINT
56
- self.format = DEFAULT_FORMAT
57
- self.directions_service = DEFAULT_DIRECTIONS_SERVICE
58
- self.places_service = DEFAULT_PLACES_SERVICE
59
- self.place_details_service = DEFAULT_PLACE_DETAILS_SERVICE
60
- self.geocode_service = DEFAULT_GEOCODE_SERVICE
61
- self.premier_client_id = DEFAULT_PREMIER_CLIENT_ID
62
- self.premier_key = DEFAULT_PREMIER_KEY
63
- self.api_key = DEFAULT_API_KEY
64
- self.default_language = DEFAULT_LANGUAGE
65
- self.default_params = DEFAULT_PARAMS
66
- self
67
- end
68
- end
69
- end
70
- end
@@ -1,25 +0,0 @@
1
- require File.expand_path('../api', __FILE__)
2
-
3
- module Google
4
- module Maps
5
- class Location
6
- attr_reader :address, :latitude, :longitude
7
- alias :to_s :address
8
-
9
- def initialize(address, latitude, longitude)
10
- @address = address
11
- @latitude = latitude
12
- @longitude = longitude
13
- end
14
-
15
- def lat_lng
16
- [latitude, longitude]
17
- end
18
-
19
- def self.find(address, language=:en)
20
- API.query(:geocode_service, :language => language, :address => address).results.map { |result| Location.new(result.formatted_address, result.geometry.location.lat, result.geometry.location.lng) }
21
- end
22
- end
23
-
24
- end
25
- end
@@ -1,38 +0,0 @@
1
- require File.expand_path('../api', __FILE__)
2
-
3
- module Google
4
- module Maps
5
-
6
- class Route
7
- attr_accessor :from, :to, :options
8
-
9
- def initialize(from, to, options={})
10
- options = {language: options} unless options.is_a? Hash
11
- @from, @to, @options = from, to, {language: :en}.merge(options)
12
- end
13
-
14
- def method_missing(name, *args, &block)
15
- if route.legs.first.key?(name)
16
- route.legs.first.send(name)
17
- else
18
- super
19
- end
20
- end
21
-
22
- def origin_latlong
23
- "#{self.start_location.lat},#{self.start_location.lng}"
24
- end
25
-
26
- def destination_latlong
27
- "#{self.end_location.lat},#{self.end_location.lng}"
28
- end
29
-
30
- private
31
- def route
32
- # default to the first returned route (the most efficient one)
33
- @response ||= API.query(:directions_service, @options.merge(origin: from, destination: to)).routes.first
34
- end
35
- end
36
-
37
- end
38
- end
@@ -1,5 +0,0 @@
1
- module Google
2
- module Maps
3
- VERSION = "2.2.0"
4
- end
5
- end
@@ -1,103 +0,0 @@
1
- require File.expand_path('../../spec_helper', __FILE__)
2
-
3
- describe Google::Maps::API do
4
- it "should raise a custom exception when the query fails by net" do
5
- HTTPClient.any_instance.unstub(:get_content)
6
-
7
- Google::Maps.end_point = "http://unknown.tld/"
8
- lambda{ Google::Maps.distance("Amsterdam", "Deventer") }.should raise_error(Google::Maps::InvalidResponseException)
9
- Google::Maps.end_point = "http://unknown-domain-asdasdasdas123123zxcasd.com/"
10
- lambda{ Google::Maps.distance("Amsterdam", "Deventer") }.should raise_error(Google::Maps::InvalidResponseException)
11
- Google::Maps.end_point = "http://www.google.com/404"
12
- lambda{ Google::Maps.distance("Amsterdam", "Deventer") }.should raise_error(Google::Maps::InvalidResponseException)
13
- end
14
-
15
- it "should raise a custom exception when the query fails by Google" do
16
- stub_response("over_query_limit.json")
17
- lambda{ Google::Maps.distance("Amsterdam", "Deventer") }.should raise_error(Google::Maps::InvalidResponseException)
18
- end
19
-
20
- it "should raise a custom exception when there are no results" do
21
- stub_response("zero-results.json")
22
- lambda{ Google::Maps.distance("Blah blah", "Jalala") }.should raise_error(Google::Maps::ZeroResultsException)
23
- end
24
-
25
- it "should raise a custom exception that is rescue-able" do
26
- stub_response("zero-results.json")
27
- begin
28
- Google::Maps.distance("Blah blah", "Jalala")
29
- rescue => error
30
- @error = error
31
- ensure
32
- @error.should_not be_nil
33
- @error.should be_a_kind_of StandardError
34
- end
35
- end
36
-
37
- describe "premier signing" do
38
- before :each do
39
- Google::Maps.configure do |config|
40
- config.premier_client_id = "clientID"
41
- config.premier_key = "vNIXE0xscrmjlyV-12Nj_BvUPaw="
42
- end
43
- end
44
-
45
- it "should raise an exception when a client id is set but no key" do
46
- Google::Maps.premier_key = nil
47
- lambda{ Google::Maps.distance("Amsterdam", "Deventer") }.should raise_error(Google::Maps::InvalidPremierConfigurationException)
48
- end
49
-
50
- it "should sign the url parameters when a client id and premier key is set" do
51
- # http://code.google.com/apis/maps/documentation/webservices/index.html#URLSigning
52
-
53
- # Example:
54
- # Private Key: vNIXE0xscrmjlyV-12Nj_BvUPaw=
55
- # Signature: KrU1TzVQM7Ur0i8i7K3huiw3MsA=
56
- # Client ID: clientID
57
- # URL: http://maps.googleapis.com/maps/api/geocode/json?address=New+York&sensor=false&client=clientID
58
- url = "http://maps.google.com/maps/api/geocode/json?address=New+York&sensor=false&client=clientID"
59
- signed_url = Google::Maps::API.send(:premier_signing, url)
60
- signed_url.should == "#{url}&signature=KrU1TzVQM7Ur0i8i7K3huiw3MsA="
61
- end
62
-
63
- it "should allow a parsed URI object to be used for signing" do
64
- url = URI.parse("http://maps.google.com/maps/api/geocode/json?address=New+York&sensor=false&client=clientID")
65
- signed_url = Google::Maps::API.send(:premier_signing, url)
66
- signed_url.should == "#{url}&signature=KrU1TzVQM7Ur0i8i7K3huiw3MsA="
67
- end
68
-
69
- context "per service overrides" do
70
- let(:place_id) { "CpQBiAAAAGs4XDizjQoVk9NjuY3ll3aLBLafpDxaFPSJSO7icOj07IRHO4KjjcRIbKEmeSVTcG75kIvwqE7VzA8D7BFvWp8OPwgAiKMveQQUsTGfJrRG5EVd7J34hY8e5JDbaXEPOMUPIWLfiugwUfQqAImvWQCGrMG1iyOpZfaW22NNhornssEg90uxrLbwLJ7QZhwGIRIQSBc_BlD7mILqQaixzTqE1BoUbNrhbmsZYkIurvK4l9exKBryfKk" }
71
- let(:api_key) { "some_api_key" }
72
- let(:parameters) { [:premier_client_id, :premier_key, :api_key, :default_params] }
73
-
74
- before :each do
75
- parameters.each do |what|
76
- self.instance_variable_set(:"@old_#{what}", Google::Maps.send(what))
77
- end
78
-
79
- Google::Maps.configure do |config|
80
- config.premier_client_id = "gme-test"
81
- config.premier_key = "secret"
82
- config.api_key = api_key
83
- config.default_params = {place_details_service: {:use_premier_signing => false}}
84
- end
85
- end
86
-
87
- after :each do
88
- Google::Maps.configure do |config|
89
- parameters.each do |what|
90
- config.send(:"#{what}=", self.instance_variable_get(:"@old_#{what}"))
91
- end
92
- end
93
- end
94
-
95
- it "should not be used when configured for a certain service" do
96
- stub_response("place_details.json", "https://maps.googleapis.com/maps/api/place/details/json?sensor=false&language=nl&placeid=#{place_id}&key=#{api_key}")
97
-
98
- Google::Maps::place(place_id, :nl).should_not be_nil
99
- end
100
- end
101
- end
102
-
103
- end
@@ -1,15 +0,0 @@
1
- require File.expand_path('../../spec_helper', __FILE__)
2
- require 'logger'
3
-
4
- describe Google::Maps::Logger do
5
- it "should be able to log messages when a log output is set" do
6
- # fake an exception
7
- HTTPClient.any_instance.expects(:get_content).raises("test exception")
8
-
9
- # expect the logger to be called once
10
- Logger.any_instance.expects(:error).at_least_once
11
-
12
- # trigger the exception
13
- lambda{ Google::Maps.distance("Amsterdam", "Deventer") }.should raise_error
14
- end
15
- end
@@ -1,32 +0,0 @@
1
- require File.expand_path('../../spec_helper', __FILE__)
2
-
3
- describe Google::Maps::PlaceDetails do
4
- let(:place_id) { "CpQBiAAAAGs4XDizjQoVk9NjuY3ll3aLBLafpDxaFPSJSO7icOj07IRHO4KjjcRIbKEmeSVTcG75kIvwqE7VzA8D7BFvWp8OPwgAiKMveQQUsTGfJrRG5EVd7J34hY8e5JDbaXEPOMUPIWLfiugwUfQqAImvWQCGrMG1iyOpZfaW22NNhornssEg90uxrLbwLJ7QZhwGIRIQSBc_BlD7mILqQaixzTqE1BoUbNrhbmsZYkIurvK4l9exKBryfKk" }
5
-
6
- context "given a canned response" do
7
- before(:each) do
8
- stub_response("place_details.json")
9
- @details = Google::Maps::PlaceDetails.find(place_id, :nl)
10
- end
11
-
12
- it "should have a place_id" do
13
- @details.place_id.should == place_id
14
- end
15
-
16
- it "should have a latlong" do
17
- @details.latitude.should == "-33.866975"
18
- @details.longitude.should =="151.195677"
19
- end
20
-
21
- it "has data containing at least address components" do
22
- @details.data.address_components.should_not be_empty
23
- end
24
-
25
- context "#address_components" do
26
- it "allows easy access by type" do
27
- @details.address_components.postal_code.long_name.should eq "2009"
28
- @details.address_components.locality.long_name.should eq "Pyrmont"
29
- end
30
- end
31
- end
32
- end