toll_booth 0.1.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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ features_rcov
7
+ coverage.data
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Dan Pickett
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,42 @@
1
+ = toll_booth
2
+ @origin = TollBooth::Location.new("4 Yawkey Way, Boston, MA")
3
+ @destination = TollBooth::Location.new("1 Fleetcenter Place, Boston, MA")
4
+ @routes = @origin.drive_to(@destination)
5
+ if @routes.found?
6
+ @routes[0].distance #distance in miles
7
+ @routes[0].drive_time #drive time in seconds
8
+ @routes[0].name #name of route (usually specified when multiple routes are returned)
9
+ @routes[0].steps #array of TollBooth::Steps to take
10
+ @routes[0].steps[0].distance #distance of step in miles
11
+ @routes[0].steps[0].description #summary of step
12
+ else
13
+ puts @routes.errors.join(",")
14
+ end
15
+
16
+ == Install
17
+ sudo gem install dpickett-toll_booth
18
+
19
+ == Links of Interest
20
+ * {Issue Tracker}[http://github.com/dpickett/toll_booth/issues]
21
+ * {RDoc}[http://rdoc.info/projects/dpickett/toll_booth]
22
+ * {WWR Profile (please recommend me if you find this software useful)}[http://workingwithrails.com/person/8076-dan-pickett]
23
+
24
+ == TODO
25
+ * Allow Configuration for Key
26
+ * Some unit testing with FakeWeb for 100% coverage
27
+ * Fix distance parsing for when distance is expressed in ft
28
+ * public transit directions
29
+ * Walking directions
30
+
31
+ == Note on Patches/Pull Requests
32
+
33
+ * Fork the project.
34
+ * Make your feature addition or bug fix.
35
+ * Add tests for it. This is important so I don't break it in a
36
+ future version unintentionally.
37
+ * Commit, do not mess with rakefile, version, or history.
38
+ * Send me a pull request. Bonus points for topic branches.
39
+
40
+ == Copyright
41
+
42
+ Copyright (c) 2009 Dan Pickett. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,109 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "toll_booth"
8
+ gem.summary = %Q{API Wrapper for Google Directions}
9
+ gem.description = %Q{API Wrapper for Google Directions}
10
+ gem.email = "dpickett@enlightsolutions.com"
11
+ gem.homepage = "http://github.com/dpickett/toll_booth"
12
+ gem.authors = ["Dan Pickett"]
13
+ gem.add_dependency("jnunemaker-httparty", ">= 0.4.4")
14
+ gem.add_dependency("hpoydar-chronic_duration", ">= 0.7.4")
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'lib' << 'test'
25
+ test.pattern = 'test/**/*_test.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+ namespace :rcov do
30
+ require 'rcov/rcovtask'
31
+ Rcov::RcovTask.new(:tests) do |test|
32
+ test.libs << 'test'
33
+ test.pattern = 'test/**/*_test.rb'
34
+ test.rcov_opts = %w{--aggregate coverage.data --exclude osx\/objc,gems\/,spec\/}
35
+ test.verbose = true
36
+ end
37
+
38
+ require 'cucumber/rake/task'
39
+ Cucumber::Rake::Task.new(:cucumber) do |t|
40
+ t.rcov = true
41
+ t.rcov_opts = %w{--aggregate coverage.data --exclude osx\/objc,gems\/,features\/,spec\/ -o "features_rcov"}
42
+ end
43
+ end
44
+
45
+ begin
46
+ require 'rcov/rcovtask'
47
+ desc "Run both specs and features to generate aggregated coverage"
48
+ task :rcov do |t|
49
+ rm "coverage.data" if File.exist?("coverage.data")
50
+ Rake::Task["rcov:cucumber"].invoke
51
+ Rake::Task["rcov:tests"].invoke
52
+ end
53
+ rescue LoadError
54
+ task :rcov do
55
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
56
+ end
57
+ end
58
+
59
+ begin
60
+ require 'cucumber/rake/task'
61
+ Cucumber::Rake::Task.new(:features)
62
+ rescue LoadError
63
+ task :features do
64
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
65
+ end
66
+ end
67
+
68
+ begin
69
+ require 'reek/rake_task'
70
+ Reek::RakeTask.new do |t|
71
+ t.fail_on_error = true
72
+ t.verbose = false
73
+ t.source_files = 'lib/**/*.rb'
74
+ end
75
+ rescue LoadError
76
+ task :reek do
77
+ abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
78
+ end
79
+ end
80
+
81
+ begin
82
+ require 'roodi'
83
+ require 'roodi_task'
84
+ RoodiTask.new do |t|
85
+ t.verbose = false
86
+ end
87
+ rescue LoadError
88
+ task :roodi do
89
+ abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
90
+ end
91
+ end
92
+
93
+ task :default => :test
94
+
95
+ require 'rake/rdoctask'
96
+ Rake::RDocTask.new do |rdoc|
97
+ if File.exist?('VERSION.yml')
98
+ config = YAML.load(File.read('VERSION.yml'))
99
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
100
+ else
101
+ version = ""
102
+ end
103
+
104
+ rdoc.rdoc_dir = 'rdoc'
105
+ rdoc.title = "toll_booth #{version}"
106
+ rdoc.rdoc_files.include('README*')
107
+ rdoc.rdoc_files.include('lib/**/*.rb')
108
+ end
109
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,25 @@
1
+ Feature: As a user of the toll_booth library
2
+ I want to retrieve direction data
3
+ So that I can interact with it
4
+
5
+ Scenario: Get Routes From a Simple Trip
6
+ Given I'm starting at "4 Yawkey Way, Boston, MA"
7
+ And I want to go to "1 Fleetcenter Place, Boston, MA"
8
+ When I get driving directions
9
+ Then I should get a list of possible routes
10
+ And the first route should have a "distance"
11
+ And the first route should have "travel_time"
12
+ And the first route should have a list of "steps"
13
+
14
+ Scenario: Invalid Destination
15
+ Given I'm starting at "4 Yawkey Way, Boston, MA"
16
+ And I want to go to "Foobar"
17
+ When I get driving directions
18
+ Then I should get "1" routing error
19
+
20
+ Scenario: Invalid Origin
21
+ Given I'm starting at "Foobar"
22
+ And I want to go to "1 Fleetcenter Place, Boston, MA"
23
+ When I get driving directions
24
+ Then I should get "1" routing error
25
+
@@ -0,0 +1,22 @@
1
+ When /^I get driving directions$/ do
2
+ @routes = @origin.drive_to(@destinations)
3
+ end
4
+
5
+ Then /^I should get a list of possible routes$/ do
6
+ assert !@routes.found?
7
+ end
8
+
9
+ Then /^the first route should have (a\s)?"(.*)"$/ do |a, attribute|
10
+ assert_not_nil @routes[0].send(attribute)
11
+ end
12
+
13
+ Then /^the first route should have a list of "([^\"]*)"$/ do |set|
14
+ assert_instance_of Array, @routes[0].send(set)
15
+ assert !@routes[0].send(set).empty?
16
+ end
17
+
18
+
19
+ Then /^I should get "([^\"]*)" routing error$/ do |error_qty|
20
+ assert_equal error_qty.to_i, @routes.errors.size
21
+ end
22
+
@@ -0,0 +1,9 @@
1
+ Given /^I'm starting at "([^\"]*)"$/ do |location|
2
+ @origin = TollBooth::Location.new(location)
3
+ end
4
+
5
+ Given /^I want to go to "([^\"]*)"$/ do |location|
6
+ @destinations ||= []
7
+ @destinations << TollBooth::Location.new(location)
8
+ end
9
+
File without changes
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require 'toll_booth'
3
+
4
+ require 'test/unit/assertions'
5
+
6
+ World(Test::Unit::Assertions)
@@ -0,0 +1,37 @@
1
+ module TollBooth
2
+ # Represents a location that you would want directions from or to
3
+ # A location has the following attributes:
4
+ # * description
5
+ class Location
6
+ attr_accessor :description
7
+
8
+ # create a new location
9
+ # @param description [String] address or zipcode of the location
10
+ def initialize(description)
11
+ @description = description
12
+ end
13
+
14
+ # get driving routes to the destinations specified
15
+ # @example
16
+ # @origin = TollBooth::Location.new("4 Yawkey Way, Boston, MA")
17
+ # @destination = TollBooth::Location.new("1 Fleetcenter Place, Boston, MA")
18
+ # @routes = @origin.drive_to(@destination)
19
+ # if @routes.found?
20
+ # @routes[0].distance #distance in miles
21
+ # @routes[0].drive_time #drive time in seconds
22
+ # @routes[0].name #name of route (usually specified when multiple routes are returned)
23
+ # @routes[0].steps #array of TollBooth::Steps to take
24
+ # @routes[0].steps[0].distance #distance of step in miles
25
+ # @routes[0].steps[0].description #summary of step
26
+ # else
27
+ # puts @routes.errors.join(",")
28
+ # end
29
+ # @param destinations [TollBooth::Location, Array] a single location or list of locations to drive to
30
+ # @return [TollBooth::RouteCollection] a collection of potential routes to specified destination(s)
31
+ def drive_to(destinations)
32
+ destinations = [destinations] if !destinations.is_a?(Array)
33
+
34
+ TollBooth::Route.find(self, destinations)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,62 @@
1
+ module TollBooth
2
+ class Route
3
+ include HTTParty
4
+ attr_accessor :name, :steps, :distance, :travel_time
5
+
6
+ default_params(
7
+ :output => "json"
8
+ )
9
+ base_uri "http://maps.google.com/maps/nav"
10
+
11
+ class << self
12
+ # get driving directions from the origin to the specified destination(s)
13
+ # @param origin [TollBooth::Location] the starting point for the trip
14
+ # @param destinations [Array] a list of destinations to drive to
15
+ # @return [TollBooth::RouteCollection] a list of potential routes for the trip
16
+ def find(origin, destinations)
17
+ response = get("",
18
+ :query => {:q => "from: #{origin.description} " +
19
+ destinations.collect{|d| " to: #{d.description}"}.join("")})
20
+ routes = parse(response)
21
+
22
+ routes
23
+ end
24
+
25
+ # parses response from google
26
+ # @param the response received from google
27
+ # @return [TollBooth::RouteCollection] returns a route collection based on the request
28
+ def parse(response)
29
+ resp = JSON.parse(response.body)
30
+
31
+ code = response["Status"]["code"]
32
+ routes = TollBooth::RouteCollection.new
33
+ if code == 200
34
+ resp["Directions"]["Routes"].each do |r|
35
+ route = new
36
+ route.distance = r["Distance"]["html"].gsub("&nbsp;mi", "").to_f
37
+ route.travel_time = ChronicDuration.parse(r["Duration"]["html"])
38
+ route.steps = TollBooth::RouteStep.parse(r["Steps"])
39
+
40
+ routes << route
41
+ end
42
+
43
+ else
44
+ routes.errors = [error_for(code)]
45
+ end
46
+ routes
47
+ end
48
+
49
+ private
50
+ # get a friently error message for the status code specified
51
+ # @param code [Integer] code to translate
52
+ # @return [String] a friendly error message
53
+ def error_for(code)
54
+ if code == 602
55
+ "Bad Address Specified"
56
+ elsif code == 500
57
+ "Server Error"
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,18 @@
1
+ module TollBooth
2
+ # a collection of routes received from google after requesting directions
3
+ # if an error occurs, the collection will be empty and the errors attribute will
4
+ # be populated
5
+ class RouteCollection < Array
6
+ attr_accessor :errors
7
+ def initialize(size = 0, obj = nil)
8
+ super
9
+ @errors = []
10
+ end
11
+
12
+ # where routes found?
13
+ # @return [Boolean] whether routes were found or not
14
+ def found?
15
+ empty?
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,38 @@
1
+ module TollBooth
2
+ #a direction to take for a given route
3
+ #direction steps have the following attributes
4
+ # * distance (in miles)
5
+ # * travel_time (in seconds)
6
+ # * latitude
7
+ # * longitude
8
+ # * html_description
9
+ # * description (html stripped)
10
+ class RouteStep
11
+ attr_accessor :distance, :travel_time, :latitude, :longitude, :html_description
12
+
13
+ # strips any html from the html_description_attribute
14
+ # @return [String]
15
+ def description
16
+ @html_description.gsub(/<\/?[^>]*>/, "")
17
+ end
18
+
19
+ class << self
20
+ # parses the step from the json supplied
21
+ def parse(json)
22
+ route_steps = []
23
+ json.each do |s|
24
+ route_step = new
25
+ route_step.html_description = s["descriptionHtml"]
26
+ route_step.travel_time = s["Duration"]["seconds"]
27
+ route_step.distance = s["Distance"]["html"]
28
+ route_step.latitude = s["Point"]["coordinates"][0]
29
+ route_step.longitude = s["Point"]["coordinates"][1]
30
+
31
+ route_steps << route_step
32
+ end
33
+
34
+ route_steps
35
+ end
36
+ end
37
+ end
38
+ end
data/lib/toll_booth.rb ADDED
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+
3
+ require "httparty"
4
+ require "json"
5
+ require "chronic_duration"
6
+
7
+ require "toll_booth/route_collection"
8
+ require "toll_booth/route_step"
9
+ require "toll_booth/route"
10
+ require "toll_booth/location"
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'toll_booth'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: toll_booth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Dan Pickett
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-08-06 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: jnunemaker-httparty
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.4.4
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hpoydar-chronic_duration
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.7.4
34
+ version:
35
+ description: API Wrapper for Google Directions
36
+ email: dpickett@enlightsolutions.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - .document
46
+ - .gitignore
47
+ - LICENSE
48
+ - README.rdoc
49
+ - Rakefile
50
+ - VERSION
51
+ - features/get_directions.feature
52
+ - features/step_definitions/direction_steps.rb
53
+ - features/step_definitions/location_steps.rb
54
+ - features/step_definitions/toll_booth_steps.rb
55
+ - features/support/env.rb
56
+ - lib/toll_booth.rb
57
+ - lib/toll_booth/location.rb
58
+ - lib/toll_booth/route.rb
59
+ - lib/toll_booth/route_collection.rb
60
+ - lib/toll_booth/route_step.rb
61
+ - test/test_helper.rb
62
+ has_rdoc: true
63
+ homepage: http://github.com/dpickett/toll_booth
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --charset=UTF-8
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.3.5
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: API Wrapper for Google Directions
90
+ test_files:
91
+ - test/test_helper.rb