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.
Files changed (30) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +4 -0
  3. data/CONTRIBUTING.md +34 -0
  4. data/LICENSE +20 -0
  5. data/README.md +98 -0
  6. data/Rakefile +42 -0
  7. data/azimuth.gemspec +31 -0
  8. data/lib/azimuth.rb +25 -0
  9. data/lib/azimuth/client.rb +26 -0
  10. data/lib/azimuth/client/route_matrix.rb +38 -0
  11. data/lib/azimuth/configuration.rb +43 -0
  12. data/lib/azimuth/connection.rb +28 -0
  13. data/lib/azimuth/error.rb +45 -0
  14. data/lib/azimuth/request.rb +30 -0
  15. data/lib/azimuth/response/raise_error.rb +18 -0
  16. data/lib/azimuth/version.rb +5 -0
  17. data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/behaves_like_a_route_matrix_request/returns_locations_coordinates.yml +87 -0
  18. data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/behaves_like_a_route_matrix_request/returns_locations_distances_to_destination.yml +87 -0
  19. data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/behaves_like_a_route_matrix_request/returns_locations_driving_times_to_destination.yml +87 -0
  20. data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/with_all_to_all_options/it_returns_destination_informations.yml +88 -0
  21. data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/with_many_to_one_options/does_not_return_destination_informations.yml +87 -0
  22. data/spec/cassettes/Azimuth_Client_RouteMatrix/_route_matrix/with_no_optionnal_options/does_not_return_destination_informations.yml +87 -0
  23. data/spec/lib/azimuth/client/route_matrix_spec.rb +39 -0
  24. data/spec/lib/azimuth/client_spec.rb +56 -0
  25. data/spec/lib/azimuth/request_spec.rb +11 -0
  26. data/spec/lib/azimuth_spec.rb +32 -0
  27. data/spec/spec_helper.rb +52 -0
  28. data/spec/support/shared_examples/error.rb +15 -0
  29. data/spec/support/shared_examples/route_matrix_request.rb +26 -0
  30. metadata +170 -0
@@ -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
@@ -0,0 +1,4 @@
1
+ --no-private
2
+ --quiet
3
+ --markup=markdown
4
+ --exclude lib/azimuth/response
@@ -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.
@@ -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**: [![Gem Version](https://badge.fury.io/rb/azimuth.png)](http://badge.fury.io/rb/azimuth)
6
+
7
+ **Build status**:        [![Build Status](https://secure.travis-ci.org/sush/azimuth.png?branch=master)](http://travis-ci.org/sush/azimuth)
8
+
9
+ **Code metrics**:
10
+      [![Code Climate](https://codeclimate.com/github/sush/azimuth.png)](https://codeclimate.com/github/sush/azimuth)
11
+ [![Coverage Status](https://coveralls.io/repos/sush/azimuth/badge.png?branch=master)](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.
@@ -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
@@ -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
@@ -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