azimuth 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.yardopts +4 -0
- data/CONTRIBUTING.md +34 -0
- data/LICENSE +20 -0
- data/README.md +98 -0
- data/Rakefile +42 -0
- data/azimuth.gemspec +31 -0
- data/lib/azimuth.rb +25 -0
- data/lib/azimuth/client.rb +26 -0
- data/lib/azimuth/client/route_matrix.rb +38 -0
- data/lib/azimuth/configuration.rb +43 -0
- data/lib/azimuth/connection.rb +28 -0
- data/lib/azimuth/error.rb +45 -0
- data/lib/azimuth/request.rb +30 -0
- data/lib/azimuth/response/raise_error.rb +18 -0
- data/lib/azimuth/version.rb +5 -0
- data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/behaves_like_a_route_matrix_request/returns_locations_coordinates.yml +87 -0
- data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/behaves_like_a_route_matrix_request/returns_locations_distances_to_destination.yml +87 -0
- data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/behaves_like_a_route_matrix_request/returns_locations_driving_times_to_destination.yml +87 -0
- data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/with_all_to_all_options/it_returns_destination_informations.yml +88 -0
- data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/with_many_to_one_options/does_not_return_destination_informations.yml +87 -0
- data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/with_no_optionnal_options/does_not_return_destination_informations.yml +87 -0
- data/spec/lib/azimuth/client/route_matrix_spec.rb +39 -0
- data/spec/lib/azimuth/client_spec.rb +56 -0
- data/spec/lib/azimuth/request_spec.rb +11 -0
- data/spec/lib/azimuth_spec.rb +32 -0
- data/spec/spec_helper.rb +52 -0
- data/spec/support/shared_examples/error.rb +15 -0
- data/spec/support/shared_examples/route_matrix_request.rb +26 -0
- metadata +170 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2bb19f0b0c81b19c9ef79e3e5ecd08850c9c302c
|
4
|
+
data.tar.gz: 9d58a7bfda4e2ff8b6a3d822e4e2e016d9f04b90
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: eafec56b6419352f70e9ffee73cd8ad57428bb38934212d777f2e9ac865b3fec7b6a3b88e95082e849657e59973ed80ecd225c116bdda9e5cec23475d8299e42
|
7
|
+
data.tar.gz: 19966e521427518e548a14b9a23663290b505efe5f0bdef8ff94a57f3b2090ef3d8f52ca03644083fd047ec37a1d4099a572dbd825c509a194c20f040ccbb531
|
data/.yardopts
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
## Running the test suite
|
4
|
+
|
5
|
+
bundle exec rake spec
|
6
|
+
|
7
|
+
### Code quality
|
8
|
+
|
9
|
+
Code quality is checked with [cane](https://github.com/square/cane) configured in `Rakefile`.
|
10
|
+
|
11
|
+
Build fails if code quality thresholds **are not met**.
|
12
|
+
|
13
|
+
### Code coverage
|
14
|
+
|
15
|
+
When running the test suite a test coverage report is generated with [SimpleCov](https://github.com/colszowka/simplecov) in `coverage/index.html`.
|
16
|
+
|
17
|
+
Build fails if coverage is below **99%**.
|
18
|
+
|
19
|
+
## Writing new tests
|
20
|
+
Azimuth uses [VCR](https://github.com/vcr/vcr) for recording and playing back API fixtures (in `spec/cassettes`) during test runs.
|
21
|
+
|
22
|
+
If you need to record new cassettes you have to provide your MapQuest API key in `ENV['MAP_QUEST_API_KEY']` (stripped automaticaly from the cassette before being saved on disk).
|
23
|
+
|
24
|
+
## Documentation
|
25
|
+
|
26
|
+
Documentation is generated with [YARD](http://yardoc.org/).
|
27
|
+
|
28
|
+
## Workflow
|
29
|
+
|
30
|
+
1. Fork [Azimuth](https://github.com/sush/azimuth)
|
31
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
32
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
33
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
34
|
+
5. Create a new Pull Request
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) [2014] [Aylic Petit]
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# Azimuth
|
2
|
+
|
3
|
+
Simple Ruby wrapper for the [MapQuest Directions API](http://www.mapquestapi.com/directions).
|
4
|
+
|
5
|
+
**Current version**: [](http://badge.fury.io/rb/azimuth)
|
6
|
+
|
7
|
+
**Build status**: [](http://travis-ci.org/sush/azimuth)
|
8
|
+
|
9
|
+
**Code metrics**:
|
10
|
+
[](https://codeclimate.com/github/sush/azimuth)
|
11
|
+
[](https://coveralls.io/r/sush/azimuth?branch=master)
|
12
|
+
|
13
|
+
**Ruby support**:
|
14
|
+
|
15
|
+
- 1.9.2
|
16
|
+
- 1.9.3
|
17
|
+
- 2.0.0
|
18
|
+
- 2.1.0
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Install via Rubygems
|
23
|
+
|
24
|
+
gem install azimuth
|
25
|
+
|
26
|
+
or add to your Gemfile
|
27
|
+
|
28
|
+
gem 'azimuth'
|
29
|
+
|
30
|
+
### Configuration
|
31
|
+
|
32
|
+
API methods are available as module methods
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
Azimuth.configure do |c|
|
36
|
+
c.api_endpoint = 'http://newendpoint/'
|
37
|
+
c.api_key = 'YOUR_MAP_QUEST_API_KEY'
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
or as client instance methods
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
Azimuth::Client.new(
|
45
|
+
api_endpoint: 'http://newendpoint/',
|
46
|
+
api_key: 'YOUR_MAP_QUEST_API_KEY',
|
47
|
+
)
|
48
|
+
```
|
49
|
+
|
50
|
+
## Authentication
|
51
|
+
|
52
|
+
Azimuth only supports authentication via an API key.
|
53
|
+
|
54
|
+
You can request one following these [steps](http://developer.mapquest.com/web/products/open).
|
55
|
+
|
56
|
+
## Usage
|
57
|
+
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
locations = Azimuth.route_matrix(["48.843079, 2.314442", "48.869061, 2.383329"])
|
61
|
+
p locations
|
62
|
+
# => [{"latitude"=>48.869061, "longitude"=>2.383329, "time"=>0, "distance"=>0}]
|
63
|
+
|
64
|
+
# etc…
|
65
|
+
```
|
66
|
+
|
67
|
+
## Features
|
68
|
+
|
69
|
+
Azimuth supports the following MapQuest Directions API methods:
|
70
|
+
|
71
|
+
- [Route Matrix](http://www.mapquestapi.com/directions/#matrix)
|
72
|
+
|
73
|
+
Complete Azimuth public API's documentation [here](http://rubydoc.info/gems/azimuth/frames).
|
74
|
+
|
75
|
+
|
76
|
+
## Similar libraries
|
77
|
+
|
78
|
+
- [mapquest](https://github.com/ggordan/mapquest)
|
79
|
+
|
80
|
+
## Versioning
|
81
|
+
Azimuth follows the principles of [semantic versioning](http://semver.org).
|
82
|
+
|
83
|
+
1. Patch level releases contain only bug fixes.
|
84
|
+
2. Minor releases contain backward-compatible new features.
|
85
|
+
3. Major new releases contain backwards-incompatible changes to the public API.
|
86
|
+
|
87
|
+
## Contributing
|
88
|
+
|
89
|
+
Pull Requests are welcome !
|
90
|
+
|
91
|
+
Please refer to the [Contributing guide](https://github.com/sush/azimuth/blob/master/CONTRIBUTING.md) for more details on how to run the test suite and to contribute.
|
92
|
+
|
93
|
+
|
94
|
+
## Copyright
|
95
|
+
|
96
|
+
Copyright © 2014 Aylic Petit
|
97
|
+
|
98
|
+
Released under the terms of the MIT licence. See the [LICENSE](https://github.com/sush/azimuth/blob/master/LICENSE) file for more details.
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'cane/rake_task'
|
9
|
+
|
10
|
+
desc 'Run cane to check quality metrics'
|
11
|
+
Cane::RakeTask.new(:quality) do |cane|
|
12
|
+
cane.add_threshold 'coverage/.last_run.json', :>=, 99
|
13
|
+
cane.abc_glob = '{lib}/**/*.rb'
|
14
|
+
cane.abc_max = 15
|
15
|
+
cane.style_measure = 105
|
16
|
+
cane.style_exclude = %w[spec/spec_helper.rb]
|
17
|
+
cane.canefile = '.cane'
|
18
|
+
end
|
19
|
+
rescue LoadError
|
20
|
+
end
|
21
|
+
|
22
|
+
namespace :doc do
|
23
|
+
begin
|
24
|
+
require 'yard'
|
25
|
+
|
26
|
+
YARD::Rake::YardocTask.new do |task|
|
27
|
+
task.files = ['README.md', 'LICENSE.md', 'lib/**/*.rb']
|
28
|
+
task.options = [
|
29
|
+
'--output-dir', 'doc/yard',
|
30
|
+
'--markup', 'markdown'
|
31
|
+
]
|
32
|
+
end
|
33
|
+
rescue LoadError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Rake::Task[:spec].enhance do
|
38
|
+
Rake::Task[:quality].invoke
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :spec
|
42
|
+
task :default => :spec
|
data/azimuth.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'azimuth/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = 'azimuth'
|
8
|
+
gem.version = Azimuth::VERSION.dup
|
9
|
+
gem.license = 'MIT'
|
10
|
+
|
11
|
+
gem.summary = %q{MapQuest Direction API Ruby wrapper}
|
12
|
+
gem.description = %q{Simple Ruby wrapper for the MapQuest Direction API.}
|
13
|
+
gem.homepage = 'https://github.com/sush/azimuth'
|
14
|
+
|
15
|
+
gem.authors = ['Aylic Petit']
|
16
|
+
gem.email = ['sush@users.noreply.github.com']
|
17
|
+
|
18
|
+
gem.required_ruby_version = '>= 1.9.2'
|
19
|
+
|
20
|
+
gem.files = %w[.yardopts LICENSE README.md CONTRIBUTING.md Rakefile azimuth.gemspec]
|
21
|
+
gem.files += Dir.glob('{spec,lib}/**/*.rb')
|
22
|
+
gem.require_paths = ['lib']
|
23
|
+
gem.test_files = Dir.glob('spec/**/*')
|
24
|
+
|
25
|
+
gem.add_development_dependency 'bundler', '~> 1.0'
|
26
|
+
gem.add_dependency 'faraday', '~> 0.8.9'
|
27
|
+
gem.add_dependency 'faraday_middleware', '~> 0.9.0'
|
28
|
+
gem.add_dependency 'hashie', '~>2.0.5'
|
29
|
+
gem.add_dependency 'json', '~>1.8.1'
|
30
|
+
gem.add_dependency 'multi_json', '~>1.8.4'
|
31
|
+
end
|
data/lib/azimuth.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'azimuth/configuration'
|
2
|
+
require 'azimuth/client'
|
3
|
+
|
4
|
+
# Ruby wrapper for MapQuest Directions API
|
5
|
+
module Azimuth
|
6
|
+
extend Configuration
|
7
|
+
|
8
|
+
class << self
|
9
|
+
# Delegates to Azimuth::Client#new
|
10
|
+
def new(options={})
|
11
|
+
Azimuth::Client.new(options)
|
12
|
+
end
|
13
|
+
|
14
|
+
# @private
|
15
|
+
def method_missing(method, *args, &block)
|
16
|
+
return super unless new.respond_to?(method)
|
17
|
+
new.send(method, *args, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @private
|
21
|
+
def respond_to?(method, include_private=false)
|
22
|
+
new.respond_to?(method, include_private) || super(method, include_private)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'azimuth/connection'
|
2
|
+
require 'azimuth/request'
|
3
|
+
|
4
|
+
require 'azimuth/client/route_matrix'
|
5
|
+
|
6
|
+
module Azimuth
|
7
|
+
# Client for the MapQuest Directions API
|
8
|
+
#
|
9
|
+
# @see http://www.mapquestapi.com/directions
|
10
|
+
class Client
|
11
|
+
attr_accessor(*Configuration::VALID_OPTIONS)
|
12
|
+
|
13
|
+
def initialize(options={})
|
14
|
+
options = Azimuth.options.merge(options)
|
15
|
+
|
16
|
+
Configuration::VALID_OPTIONS.each do |key|
|
17
|
+
send("#{key}=", options[key])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
include Azimuth::Connection
|
22
|
+
include Azimuth::Request
|
23
|
+
|
24
|
+
include Azimuth::Client::RouteMatrix
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Azimuth
|
2
|
+
class Client
|
3
|
+
# Methods for the Route Matrix API
|
4
|
+
#
|
5
|
+
# @see http://www.mapquestapi.com/directions/#matrix
|
6
|
+
module RouteMatrix
|
7
|
+
# Get calculation of the distances and driving times between locations.
|
8
|
+
# @param locations [Array] the locations
|
9
|
+
# @param options [Hash] optional parameters
|
10
|
+
# @option options [Hash] :manyToOne parameter
|
11
|
+
# @option options [Hash] :allToAll parameter
|
12
|
+
# @return [Hashie::Mash] the locations and their distance and traveling time
|
13
|
+
# @see http://www.mapquestapi.com/directions/#matrix
|
14
|
+
# @example
|
15
|
+
# Azimuth.route_matrix(['48.843079, 2.314442', '48.869061, 2.383329']
|
16
|
+
def route_matrix(locations, options={})
|
17
|
+
parameters = { locations: locations, options: options }
|
18
|
+
|
19
|
+
format_response(post('routematrix', parameters))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def format_response(response)
|
25
|
+
response.locations.delete_at(0) unless response.allToAll
|
26
|
+
|
27
|
+
response.locations.each_with_index.map do |location, i|
|
28
|
+
Hashie::Mash.new(
|
29
|
+
latitude: location.latLng.lat,
|
30
|
+
longitude: location.latLng.lng,
|
31
|
+
time: response.time[i],
|
32
|
+
distance: response.distance[i]
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Azimuth
|
2
|
+
# Methods for Azimuth configuration
|
3
|
+
module Configuration
|
4
|
+
# Configurable options
|
5
|
+
VALID_OPTIONS = [
|
6
|
+
:api_endpoint,
|
7
|
+
:api_key,
|
8
|
+
].freeze
|
9
|
+
|
10
|
+
# Default MapQuest Directions API endpoint
|
11
|
+
DEFAULT_API_ENDPOINT = 'http://www.mapquestapi.com/directions/v2/'
|
12
|
+
|
13
|
+
attr_accessor(*VALID_OPTIONS)
|
14
|
+
|
15
|
+
# @private
|
16
|
+
def self.extended(base_obj)
|
17
|
+
base_obj.initialize_default_options
|
18
|
+
end
|
19
|
+
|
20
|
+
# Set configuration options using a block
|
21
|
+
def configure
|
22
|
+
yield self
|
23
|
+
end
|
24
|
+
|
25
|
+
# Default options
|
26
|
+
def options
|
27
|
+
VALID_OPTIONS.inject({}){ |o, k| o.merge!(k => send(k)) }
|
28
|
+
end
|
29
|
+
|
30
|
+
# Initialize default options
|
31
|
+
def initialize_default_options
|
32
|
+
self.api_endpoint = DEFAULT_API_ENDPOINT
|
33
|
+
self.api_key = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
# Reset configuration options to default values
|
37
|
+
def reset!
|
38
|
+
initialize_default_options
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'faraday_middleware'
|
2
|
+
require 'azimuth/response/raise_error'
|
3
|
+
|
4
|
+
module Azimuth
|
5
|
+
# Faraday connection methods
|
6
|
+
module Connection
|
7
|
+
private
|
8
|
+
|
9
|
+
def connection
|
10
|
+
options = {
|
11
|
+
ssl: { verify: false },
|
12
|
+
url: self.api_endpoint,
|
13
|
+
}
|
14
|
+
|
15
|
+
connection = Faraday.new(options) do |conn|
|
16
|
+
conn.response(:mashify)
|
17
|
+
conn.response(:json, content_type: /\bjson$/)
|
18
|
+
|
19
|
+
conn.use(Azimuth::Response::RaiseError)
|
20
|
+
conn.use(FaradayMiddleware::FollowRedirects, limit: 3)
|
21
|
+
|
22
|
+
conn.adapter(Faraday.default_adapter)
|
23
|
+
end
|
24
|
+
|
25
|
+
connection
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
module Azimuth
|
4
|
+
# Custom error class
|
5
|
+
class Error < StandardError
|
6
|
+
# Returns the Error based on status and response message.
|
7
|
+
#
|
8
|
+
# @param [Hash] response HTTP response
|
9
|
+
# @return [Azimuth::Error]
|
10
|
+
def self.from_response(response)
|
11
|
+
parsed_response_info = ::MultiJson.load(response[:body])['info']
|
12
|
+
|
13
|
+
status_code = parsed_response_info['statuscode']
|
14
|
+
|
15
|
+
return if status_code == 0
|
16
|
+
|
17
|
+
if error_message = parsed_response_info['messages']
|
18
|
+
error_message = error_message.join(' ')
|
19
|
+
end
|
20
|
+
|
21
|
+
case status_code
|
22
|
+
when 400
|
23
|
+
raise Azimuth::ErrorWithInput, error_message
|
24
|
+
when 403
|
25
|
+
raise Azimuth::KeyRelatedError, error_message
|
26
|
+
when 500
|
27
|
+
raise Azimuth::UnknownError, error_message
|
28
|
+
when 600...699
|
29
|
+
raise Azimuth::OtherError, error_message
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Raised when API returns 400 error code
|
35
|
+
class ErrorWithInput < Error; end
|
36
|
+
|
37
|
+
# Raised when API returns 403 error code
|
38
|
+
class KeyRelatedError < Error; end
|
39
|
+
|
40
|
+
# Raised when API returns 500 error code
|
41
|
+
class UnknownError < Error; end
|
42
|
+
|
43
|
+
# Raised when API returns error code between 600 and 699
|
44
|
+
class OtherError < Error; end
|
45
|
+
end
|