nextbus 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +22 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +29 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +27 -0
- data/VERSION +1 -0
- data/doc/ERM.graffle +1318 -0
- data/doc/MBTA_XML_Feed_Trial_Docs_13Nov09-1.pdf +0 -0
- data/lib/attr_with_default.rb +51 -0
- data/lib/instantiate_with_attrs.rb +12 -0
- data/lib/nextbus.rb +10 -0
- data/lib/nextbus/agency.rb +18 -0
- data/lib/nextbus/client.rb +70 -0
- data/lib/nextbus/direction.rb +18 -0
- data/lib/nextbus/mash_extensions.rb +12 -0
- data/lib/nextbus/prediction.rb +18 -0
- data/lib/nextbus/report.rb +10 -0
- data/lib/nextbus/route.rb +18 -0
- data/lib/nextbus/stop.rb +18 -0
- data/lib/nextbus/string_extensions.rb +16 -0
- data/lib/nextbus/vehicle.rb +18 -0
- data/nextbus.gemspec +106 -0
- data/test/fixtures/agency_list.xml +5 -0
- data/test/fixtures/error.xml +6 -0
- data/test/fixtures/predictions.xml +12 -0
- data/test/fixtures/predictions_for_multi_stops.xml +21 -0
- data/test/fixtures/route_config.xml +755 -0
- data/test/fixtures/route_list.xml +5 -0
- data/test/fixtures/vehicle_locations.xml +11 -0
- data/test/helper.rb +78 -0
- data/test/unit/test_agency.rb +56 -0
- data/test/unit/test_attr_with_default.rb +158 -0
- data/test/unit/test_client.rb +107 -0
- data/test/unit/test_direction.rb +59 -0
- data/test/unit/test_instantiate_with_attrs.rb +31 -0
- data/test/unit/test_mash_extensions.rb +45 -0
- data/test/unit/test_nextbus.rb +9 -0
- data/test/unit/test_prediction.rb +47 -0
- data/test/unit/test_report.rb +34 -0
- data/test/unit/test_route.rb +51 -0
- data/test/unit/test_stop.rb +64 -0
- data/test/unit/test_string_extensions.rb +33 -0
- data/test/unit/test_vehicle.rb +52 -0
- data/vendor/cache/columnize-0.3.1.gem +0 -0
- data/vendor/cache/crack-0.1.6.gem +0 -0
- data/vendor/cache/hashie-0.1.8.gem +0 -0
- data/vendor/cache/httparty-0.5.2.gem +0 -0
- data/vendor/cache/linecache-0.43.gem +0 -0
- data/vendor/cache/mocha-0.9.8.gem +0 -0
- data/vendor/cache/rake-0.8.7.gem +0 -0
- data/vendor/cache/ruby-debug-0.10.3.gem +0 -0
- data/vendor/cache/ruby-debug-base-0.10.3.gem +0 -0
- metadata +121 -0
Binary file
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# http://snippets.dzone.com/posts/show/4382
|
2
|
+
|
3
|
+
module AttrWithDefault
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
def attr_accessor(*args)
|
8
|
+
attrs, attrs_with_defaults = split_for_last_hash(args)
|
9
|
+
attrs_with_defaults.each do |name, default|
|
10
|
+
attr_reader_with_default name, default
|
11
|
+
attr_writer name
|
12
|
+
end
|
13
|
+
|
14
|
+
super(*attrs)
|
15
|
+
end
|
16
|
+
|
17
|
+
def attr_reader(*args)
|
18
|
+
attrs, attrs_with_defaults = split_for_last_hash(args)
|
19
|
+
attrs_with_defaults.each do |name, default|
|
20
|
+
attr_reader_with_default name, default
|
21
|
+
end
|
22
|
+
|
23
|
+
super(*attrs)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def attr_reader_with_default(name, default)
|
29
|
+
define_method(name) do
|
30
|
+
unless instance_variable_defined?("@#{name}")
|
31
|
+
instance_variable_set "@#{name}", default
|
32
|
+
end
|
33
|
+
instance_variable_get "@#{name}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def split_for_last_hash(args)
|
38
|
+
if args.last.is_a?(Hash)
|
39
|
+
[args[0...-1], args.last]
|
40
|
+
else
|
41
|
+
[args, {}]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.included(other_module)
|
48
|
+
other_module.extend ClassMethods
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
data/lib/nextbus.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'hashie'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
5
|
+
require 'instantiate_with_attrs'
|
6
|
+
require 'attr_with_default'
|
7
|
+
|
8
|
+
dir = File.join(File.dirname(__FILE__), 'nextbus')
|
9
|
+
$LOAD_PATH.unshift(dir)
|
10
|
+
Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) }
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Nextbus
|
2
|
+
class Agency
|
3
|
+
|
4
|
+
include InstantiateWithAttrs
|
5
|
+
include AttrWithDefault
|
6
|
+
|
7
|
+
attr_accessor :tag, :title, :short_title, :region_title, :routes => [], :vehicles => []
|
8
|
+
|
9
|
+
def self.all
|
10
|
+
Nextbus.client.agencies.map{|agency| new(agency) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find(id)
|
14
|
+
all.detect{|agency| agency.tag == id }
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
module Nextbus
|
3
|
+
|
4
|
+
def self.client
|
5
|
+
Nextbus::Client.instance
|
6
|
+
end
|
7
|
+
|
8
|
+
class Client
|
9
|
+
|
10
|
+
include Singleton
|
11
|
+
include HTTParty
|
12
|
+
|
13
|
+
base_uri "http://webservices.nextbus.com/service/publicXMLFeed?command="
|
14
|
+
|
15
|
+
def agencies
|
16
|
+
response = self.class.do_request("agencyList", {})
|
17
|
+
response.agency
|
18
|
+
end
|
19
|
+
|
20
|
+
def routes(agency_id)
|
21
|
+
response = self.class.do_request("routeList", {"a" => agency_id})
|
22
|
+
response.route
|
23
|
+
end
|
24
|
+
|
25
|
+
def route(agency_id, route_id)
|
26
|
+
response = self.class.do_request("routeConfig", {"a" => agency_id, "r" => route_id})
|
27
|
+
response.route
|
28
|
+
end
|
29
|
+
|
30
|
+
def predictions(agency_id, route_id, stop_id)
|
31
|
+
response = self.class.do_request("predictions", {"a" => agency_id, "r" => route_id, "s" => stop_id})
|
32
|
+
response.predictions.direction.prediction
|
33
|
+
end
|
34
|
+
|
35
|
+
def vehicles(agency_id, route_id, time=Time.now)
|
36
|
+
response = self.class.do_request("vehicleLocations", {"a" => agency_id, "r" => route_id, "t" => time.to_i.to_s})
|
37
|
+
response.vehicle
|
38
|
+
end
|
39
|
+
|
40
|
+
def directions(agency_id, route_id)
|
41
|
+
response = self.class.do_request("routeConfig", {"a" => agency_id, "r" => route_id})
|
42
|
+
response.route.direction
|
43
|
+
end
|
44
|
+
|
45
|
+
def stops(agency_id, route_id, direction_id)
|
46
|
+
response = self.class.do_request("routeConfig", {"a" => agency_id, "r" => route_id})
|
47
|
+
response.route.direction.detect{|direction| direction.tag == direction_id }.stop
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def self.do_request(resource, params)
|
53
|
+
uri = build_uri(resource, params)
|
54
|
+
response = get(uri)
|
55
|
+
mash_response_body(response)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.build_uri(resource, params)
|
59
|
+
params = params.to_a
|
60
|
+
params.map!{|pair| pair.join('=') }
|
61
|
+
params.unshift(resource)
|
62
|
+
params.join('&')
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.mash_response_body(response)
|
66
|
+
Hashie::Mash.new(response["body"])
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Nextbus
|
2
|
+
class Direction
|
3
|
+
|
4
|
+
include InstantiateWithAttrs
|
5
|
+
include AttrWithDefault
|
6
|
+
|
7
|
+
attr_accessor :tag, :title, :name, :route, :reports => [], :stops => []
|
8
|
+
|
9
|
+
def self.all(agency_id, route_id)
|
10
|
+
Nextbus.client.directions(agency_id, route_id).map{|direction| new(direction) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find(agency_id, route_id, id)
|
14
|
+
all(agency_id, route_id).detect{|direction| direction.tag == id }
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Nextbus
|
2
|
+
class Prediction
|
3
|
+
|
4
|
+
include InstantiateWithAttrs
|
5
|
+
include AttrWithDefault
|
6
|
+
|
7
|
+
attr_accessor :time, :departure, :stop
|
8
|
+
|
9
|
+
def epoch_time=(nanosecs)
|
10
|
+
self.time = Time.at(nanosecs.to_i/1000)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.all(agency_id, route_id, stop_id)
|
14
|
+
Nextbus.client.predictions(agency_id, route_id, stop_id).map{|prediction| new(prediction) }
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Nextbus
|
2
|
+
class Route
|
3
|
+
|
4
|
+
include InstantiateWithAttrs
|
5
|
+
include AttrWithDefault
|
6
|
+
|
7
|
+
attr_accessor :tag, :title, :agency, :directions => []
|
8
|
+
|
9
|
+
def self.all(agency_id)
|
10
|
+
Nextbus.client.routes(agency_id).map{|agency| new(agency) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find(agency_id, id)
|
14
|
+
new Nextbus.client.route(agency_id, id)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/lib/nextbus/stop.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Nextbus
|
2
|
+
class Stop
|
3
|
+
|
4
|
+
include InstantiateWithAttrs
|
5
|
+
include AttrWithDefault
|
6
|
+
|
7
|
+
attr_accessor :tag, :title, :lat, :lon, :id, :direction, :predictions => []
|
8
|
+
|
9
|
+
def self.all(agency_id, route_id, direction_id)
|
10
|
+
Nextbus.client.stops(agency_id, route_id, direction_id).map{|stop| new(stop) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find(agency_id, route_id, direction_id, id)
|
14
|
+
all(agency_id, route_id, direction_id).detect{|stop| stop.tag == id }
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
def underscore
|
4
|
+
self.class.underscore(self)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.underscore(camel_cased_word)
|
8
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
9
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
10
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
11
|
+
tr(" ", "_").
|
12
|
+
tr("-", "_").
|
13
|
+
downcase
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Nextbus
|
2
|
+
class Vehicle
|
3
|
+
|
4
|
+
include InstantiateWithAttrs
|
5
|
+
include AttrWithDefault
|
6
|
+
|
7
|
+
attr_accessor :id, :agency, :route, :reports => []
|
8
|
+
|
9
|
+
def self.all(agency_id, route_id)
|
10
|
+
Nextbus.client.vehicles(agency_id, route_id).map{|vehicle| new(vehicle) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find(agency_id, route_id, id)
|
14
|
+
all(agency_id, route_id).detect{|vehicle| vehicle.id == id }
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/nextbus.gemspec
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{nextbus}
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Greg Sterndale"]
|
12
|
+
s.date = %q{2010-02-23}
|
13
|
+
s.description = %q{NextBus API client}
|
14
|
+
s.email = %q{gsterndale@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".gitignore",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"doc/ERM.graffle",
|
28
|
+
"doc/MBTA_XML_Feed_Trial_Docs_13Nov09-1.pdf",
|
29
|
+
"lib/attr_with_default.rb",
|
30
|
+
"lib/instantiate_with_attrs.rb",
|
31
|
+
"lib/nextbus.rb",
|
32
|
+
"lib/nextbus/agency.rb",
|
33
|
+
"lib/nextbus/client.rb",
|
34
|
+
"lib/nextbus/direction.rb",
|
35
|
+
"lib/nextbus/mash_extensions.rb",
|
36
|
+
"lib/nextbus/prediction.rb",
|
37
|
+
"lib/nextbus/report.rb",
|
38
|
+
"lib/nextbus/route.rb",
|
39
|
+
"lib/nextbus/stop.rb",
|
40
|
+
"lib/nextbus/string_extensions.rb",
|
41
|
+
"lib/nextbus/vehicle.rb",
|
42
|
+
"nextbus.gemspec",
|
43
|
+
"test/fixtures/agency_list.xml",
|
44
|
+
"test/fixtures/error.xml",
|
45
|
+
"test/fixtures/predictions.xml",
|
46
|
+
"test/fixtures/predictions_for_multi_stops.xml",
|
47
|
+
"test/fixtures/route_config.xml",
|
48
|
+
"test/fixtures/route_list.xml",
|
49
|
+
"test/fixtures/vehicle_locations.xml",
|
50
|
+
"test/helper.rb",
|
51
|
+
"test/unit/test_agency.rb",
|
52
|
+
"test/unit/test_attr_with_default.rb",
|
53
|
+
"test/unit/test_client.rb",
|
54
|
+
"test/unit/test_direction.rb",
|
55
|
+
"test/unit/test_instantiate_with_attrs.rb",
|
56
|
+
"test/unit/test_mash_extensions.rb",
|
57
|
+
"test/unit/test_nextbus.rb",
|
58
|
+
"test/unit/test_prediction.rb",
|
59
|
+
"test/unit/test_report.rb",
|
60
|
+
"test/unit/test_route.rb",
|
61
|
+
"test/unit/test_stop.rb",
|
62
|
+
"test/unit/test_string_extensions.rb",
|
63
|
+
"test/unit/test_vehicle.rb",
|
64
|
+
"vendor/cache/columnize-0.3.1.gem",
|
65
|
+
"vendor/cache/crack-0.1.6.gem",
|
66
|
+
"vendor/cache/hashie-0.1.8.gem",
|
67
|
+
"vendor/cache/httparty-0.5.2.gem",
|
68
|
+
"vendor/cache/linecache-0.43.gem",
|
69
|
+
"vendor/cache/mocha-0.9.8.gem",
|
70
|
+
"vendor/cache/rake-0.8.7.gem",
|
71
|
+
"vendor/cache/ruby-debug-0.10.3.gem",
|
72
|
+
"vendor/cache/ruby-debug-base-0.10.3.gem"
|
73
|
+
]
|
74
|
+
s.homepage = %q{http://github.com/neweryankee/nextbus}
|
75
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
76
|
+
s.require_paths = ["lib"]
|
77
|
+
s.rubygems_version = %q{1.3.5}
|
78
|
+
s.summary = %q{NextBus API client}
|
79
|
+
s.test_files = [
|
80
|
+
"test/helper.rb",
|
81
|
+
"test/unit/test_agency.rb",
|
82
|
+
"test/unit/test_attr_with_default.rb",
|
83
|
+
"test/unit/test_client.rb",
|
84
|
+
"test/unit/test_direction.rb",
|
85
|
+
"test/unit/test_instantiate_with_attrs.rb",
|
86
|
+
"test/unit/test_mash_extensions.rb",
|
87
|
+
"test/unit/test_nextbus.rb",
|
88
|
+
"test/unit/test_prediction.rb",
|
89
|
+
"test/unit/test_report.rb",
|
90
|
+
"test/unit/test_route.rb",
|
91
|
+
"test/unit/test_stop.rb",
|
92
|
+
"test/unit/test_string_extensions.rb",
|
93
|
+
"test/unit/test_vehicle.rb"
|
94
|
+
]
|
95
|
+
|
96
|
+
if s.respond_to? :specification_version then
|
97
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
98
|
+
s.specification_version = 3
|
99
|
+
|
100
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
101
|
+
else
|
102
|
+
end
|
103
|
+
else
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<body copyright="All data copyright agencies listed below and NextBus Inc 2010.">
|
3
|
+
<agency tag="mbta" title="MBTA" regionTitle="Massachusetts"/>
|
4
|
+
<agency tag="sf-muni" title="San Francisco Muni" shortTitle="SF Muni" regionTitle="California-Northern"/>
|
5
|
+
</body>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<body copyright="All data copyright MBTA 2010.">
|
3
|
+
<predictions agencyTitle="MBTA" routeTitle="39" routeTag="39" stopTitle="105 S Huntington (Stop 22365)">
|
4
|
+
<direction title="Outbound">
|
5
|
+
<prediction seconds="745" minutes="12" epochTime="1266681828070" isDeparture="false" dirTag="out" vehicle="1041" block="S393_6"/>
|
6
|
+
<prediction seconds="1299" minutes="21" epochTime="1266681828075" isDeparture="false" dirTag="out" vehicle="1022" block="S393_7"/>
|
7
|
+
<prediction seconds="1929" minutes="32" epochTime="1266683011947" isDeparture="false" dirTag="out" vehicle="1027" block="S393_1"/>
|
8
|
+
<prediction seconds="2529" minutes="42" epochTime="1266683611947" isDeparture="false" dirTag="out" vehicle="1040" block="S393_2"/>
|
9
|
+
<prediction seconds="3129" minutes="52" epochTime="1266684211947" isDeparture="false" dirTag="out" vehicle="1037" block="S393_8"/>
|
10
|
+
</direction>
|
11
|
+
</predictions>
|
12
|
+
</body>
|