bart_api 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/lib/bart_api/api.rb +52 -0
- data/lib/bart_api/client/estimates.rb +38 -0
- data/lib/bart_api/client/routes.rb +21 -0
- data/lib/bart_api/client/stops.rb +21 -0
- data/lib/bart_api/client.rb +14 -0
- data/lib/bart_api/configuration.rb +49 -0
- data/lib/bart_api/connection.rb +23 -0
- data/lib/bart_api/connection_adapters/httparty_adapter.rb +35 -0
- data/lib/bart_api/core_ext/float.rb +5 -0
- data/lib/bart_api/core_ext/hash.rb +11 -0
- data/lib/bart_api/core_ext/integer.rb +5 -0
- data/lib/bart_api/core_ext/string.rb +21 -0
- data/lib/bart_api/models/arrival.rb +13 -0
- data/lib/bart_api/models/destination.rb +15 -0
- data/lib/bart_api/models/route.rb +21 -0
- data/lib/bart_api/models/stop.rb +40 -0
- data/lib/bart_api/models.rb +89 -0
- data/lib/bart_api/version.rb +3 -0
- data/lib/bart_api.rb +35 -0
- metadata +92 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: acf48065dee6a232f3d2696dd6ce3de6e6a28f95
|
4
|
+
data.tar.gz: 1d4aee5fe2c759ff55845523aa4acddd1b0344c9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8229a8062b76851b6fd7a677a5f544d930a55667b5d8819ae399a181bc71d79593cf0d2299a959298de762838a3683cb2ae16d3c99693e0443e4bda8a6b37955
|
7
|
+
data.tar.gz: 5d0c905ef5ba65d12804295e19f3a3dbf2af8d00e0392ddb0635ebd966b0c3d2f60d7236c7967bd43043914494106c6011fce9a86615fa68ba38b3cb36cf7bb3
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2016 Jon Egeland
|
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/lib/bart_api/api.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'memoist'
|
2
|
+
|
3
|
+
module Bart
|
4
|
+
# A base class implementing common API operations
|
5
|
+
class API
|
6
|
+
include Connection
|
7
|
+
|
8
|
+
class << self
|
9
|
+
extend Memoist
|
10
|
+
|
11
|
+
# Include another API's functionality via a new method on this API.
|
12
|
+
# For example, `include_api :routes` would include the "Routes" API into
|
13
|
+
# the "Client" API, accessible as `Client#routes`.
|
14
|
+
def include_api name
|
15
|
+
klass = self.const_get(name.to_s.constantize)
|
16
|
+
define_method(name) do
|
17
|
+
klass.new
|
18
|
+
end
|
19
|
+
self.memoize name
|
20
|
+
end
|
21
|
+
|
22
|
+
# Require all the files given in `names` that exist in the given folder
|
23
|
+
def require_all folder, *libs
|
24
|
+
libs.each do |lib|
|
25
|
+
require_relative "#{File.join(folder, lib)}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Return a singleton instance of this API
|
30
|
+
def singleton
|
31
|
+
@singleton ||= self.new
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# Perform a GET request over the connection to the given endpoint.
|
37
|
+
def get_request endpoint, opts={}, &block
|
38
|
+
connection.get endpoint, opts, &block
|
39
|
+
end
|
40
|
+
|
41
|
+
# Perform a POST request over the connection to the given endpoint.
|
42
|
+
def post_request endpoint, opts={}, &block
|
43
|
+
connection.post endpoint, opts, &block
|
44
|
+
end
|
45
|
+
|
46
|
+
# For APIs that extend Memoist, allow the user to call `refresh` as an
|
47
|
+
# alias for `flush_cache`.
|
48
|
+
def refresh
|
49
|
+
send(:flush_cache) if respond_to?(:flush_cache)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Bart
|
2
|
+
class Client::Estimates < API
|
3
|
+
RESOLUTION = 30 # seconds
|
4
|
+
|
5
|
+
def key stop_id, platform, direction
|
6
|
+
[stop_id, platform, direction]
|
7
|
+
end
|
8
|
+
|
9
|
+
# We need to memoize but never for longer than `RESOLUTION`, so rather than
|
10
|
+
# use Memoist this API maintains its own memo.
|
11
|
+
def get stop_id, platform: nil, direction: nil
|
12
|
+
@memo ||= {}
|
13
|
+
model, stored_at = @memo[[stop_id, platform, direction]]
|
14
|
+
return model if stored_at &&
|
15
|
+
Time.now - Bart.configuration.refresh_time < stored_at
|
16
|
+
|
17
|
+
parsed = get_request '/api/etd.aspx', query: {
|
18
|
+
cmd: :etd,
|
19
|
+
orig: stop_id,
|
20
|
+
plat: platform,
|
21
|
+
dir: direction
|
22
|
+
}.select { |_,v| v != nil }
|
23
|
+
|
24
|
+
parsed['root']['station'].tap do |station|
|
25
|
+
station['etd'] = [station['etd']].flatten
|
26
|
+
station['etd'].each do |etd|
|
27
|
+
etd['estimate'] = [etd['estimate']].flatten
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
model = Stop.new parsed['root']['station']
|
32
|
+
@memo[[stop_id, platform, direction]] = [model, Time.now]
|
33
|
+
model
|
34
|
+
end
|
35
|
+
alias_method :find, :get
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Bart
|
2
|
+
class Client::Routes < API
|
3
|
+
extend Memoist
|
4
|
+
|
5
|
+
# Return a list of all routes on the system.
|
6
|
+
def list
|
7
|
+
parsed = get_request '/api/route.aspx', query: { cmd: :routes }
|
8
|
+
parsed['root']['routes']['route'].map { |route| Route.new route }
|
9
|
+
end
|
10
|
+
memoize :list
|
11
|
+
alias_method :all, :list
|
12
|
+
|
13
|
+
# Return the route whose id matches the given id
|
14
|
+
def get id
|
15
|
+
parsed = get_request '/api/route.aspx', query: { cmd: :routeinfo, route: id }
|
16
|
+
Route.new parsed['root']['routes']['route']
|
17
|
+
end
|
18
|
+
memoize :get
|
19
|
+
alias_method :find, :get
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Bart
|
2
|
+
class Client::Stops < API
|
3
|
+
extend Memoist
|
4
|
+
|
5
|
+
# Return a list of all stops on the system.
|
6
|
+
def list
|
7
|
+
parsed = get_request '/api/stn.aspx', query: { cmd: :stns }
|
8
|
+
parsed['root']['stations']['station'].map { |stop| Stop.new stop }
|
9
|
+
end
|
10
|
+
memoize :list
|
11
|
+
alias_method :all, :list
|
12
|
+
|
13
|
+
# Return the route whose id matches the given id
|
14
|
+
def get id
|
15
|
+
parsed = get_request '/api/stn.aspx', query: { cmd: :stninfo, orig: id }
|
16
|
+
Stop.new parsed['root']['stations']['station']
|
17
|
+
end
|
18
|
+
memoize :get
|
19
|
+
alias_method :find, :get
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Bart
|
2
|
+
class Configuration
|
3
|
+
# The version of the BART system
|
4
|
+
attr_accessor :version
|
5
|
+
# The base URL of the BART system
|
6
|
+
attr_accessor :base_uri
|
7
|
+
# The adapter to use for network communication
|
8
|
+
attr_accessor :adapter
|
9
|
+
# The output stream to which debug information should be written
|
10
|
+
attr_accessor :debug_output
|
11
|
+
# The key used to make requests, defaulting to BART's public key.
|
12
|
+
attr_accessor :api_key
|
13
|
+
# The number of seconds real-time results are cached for.
|
14
|
+
attr_accessor :refresh_time
|
15
|
+
|
16
|
+
# The defaults to use for any configuration options that are not provided
|
17
|
+
DEFAULT_CONFIGURATION = {
|
18
|
+
adapter: :httparty,
|
19
|
+
debug_output: false,
|
20
|
+
base_uri: 'http://api.bart.gov',
|
21
|
+
refresh_time: 30,
|
22
|
+
api_key: 'MW9S-E7SL-26DU-VV8V'
|
23
|
+
}
|
24
|
+
|
25
|
+
# The options required when configuring a BART instance
|
26
|
+
REQUIRED_CONFIGURATION = [
|
27
|
+
:base_uri,
|
28
|
+
:api_key,
|
29
|
+
:refresh_time
|
30
|
+
]
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
# Apply the default set of configurations before anything else to ensure
|
34
|
+
# all options are initialized.
|
35
|
+
DEFAULT_CONFIGURATION.each do |name, value|
|
36
|
+
send("#{name}=", value)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Ensure that all required configurations have been given a value. Returns
|
41
|
+
# true if all required configuration options have been set.
|
42
|
+
def validate!
|
43
|
+
REQUIRED_CONFIGURATION.each do |name|
|
44
|
+
raise "`#{name}` is a required configuration option, but was not given a value." if send("#{name}").nil?
|
45
|
+
end
|
46
|
+
true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Bart
|
2
|
+
module Connection
|
3
|
+
extend self
|
4
|
+
|
5
|
+
# Return the connection adapter instance
|
6
|
+
def connection
|
7
|
+
@connection ||= adapter.new(Bart.configuration)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Return the class of the adapter to use for the connection
|
11
|
+
def adapter
|
12
|
+
@@adapters[Bart.configuration.adapter]
|
13
|
+
end
|
14
|
+
|
15
|
+
# Register a new class that can be used as a connection adapter
|
16
|
+
def register_adapter name, klass
|
17
|
+
(@@adapters ||= {})[name] = klass
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Include the adapters that come packaged with the gem
|
23
|
+
require_relative 'connection_adapters/httparty_adapter.rb'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
# A Connection adapter using HTTParty as the network transport
|
5
|
+
module Bart
|
6
|
+
module Connection
|
7
|
+
class HTTPartyAdapter
|
8
|
+
include HTTParty
|
9
|
+
|
10
|
+
def initialize config
|
11
|
+
self.class.base_uri config.base_uri
|
12
|
+
# Write debug information to the configured output stream
|
13
|
+
self.class.debug_output config.debug_output
|
14
|
+
@config = config
|
15
|
+
end
|
16
|
+
|
17
|
+
def defaults
|
18
|
+
{
|
19
|
+
query: { key: @config.api_key }
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def get endpoint, opts={}, &block
|
24
|
+
self.class.get(endpoint, defaults.deep_merge(opts), &block).parsed_response
|
25
|
+
end
|
26
|
+
|
27
|
+
def post endpoint, opts={}, &block
|
28
|
+
self.class.post(endpoint, defaults.deep_merge(opts), &block).parsed_response
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
register_adapter :httparty, HTTPartyAdapter
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class String
|
2
|
+
def underscore
|
3
|
+
self.dup.underscore!
|
4
|
+
end unless method_defined? :underscore
|
5
|
+
|
6
|
+
def underscore!
|
7
|
+
self.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
8
|
+
self.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
9
|
+
self.tr_s!('- ', '_')
|
10
|
+
self.downcase!
|
11
|
+
self
|
12
|
+
end unless method_defined? :underscore!
|
13
|
+
|
14
|
+
def titleize
|
15
|
+
self.tr_s('- ', '_').split('_').map(&:capitalize).join(' ')
|
16
|
+
end unless method_defined? :titleize
|
17
|
+
|
18
|
+
def constantize
|
19
|
+
self.tr_s('- ', '_').split('_').map(&:capitalize).join
|
20
|
+
end unless method_defined? :constantize
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Bart
|
2
|
+
class Arrival < Model
|
3
|
+
attribute :minutes
|
4
|
+
attribute :platform, type: Integer
|
5
|
+
attribute :direction
|
6
|
+
attribute :length, type: Integer
|
7
|
+
alias_method :train_length, :length
|
8
|
+
attribute :color
|
9
|
+
attribute :hexcolor
|
10
|
+
attribute :bikeflag, type: Integer
|
11
|
+
attribute :delay, type: Integer
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Bart
|
2
|
+
class Destination < Model
|
3
|
+
attribute :destination
|
4
|
+
alias_method :name, :destination
|
5
|
+
attribute :abbreviation
|
6
|
+
alias_method :abbr, :abbreviation
|
7
|
+
|
8
|
+
attribute :limited, type: Integer
|
9
|
+
attribute :estimate, type: Bart::Arrival, array: true
|
10
|
+
alias_method :arrivals, :estimate
|
11
|
+
|
12
|
+
primary_attribute :abbr
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Bart
|
2
|
+
class Route < Model
|
3
|
+
attribute :name
|
4
|
+
attribute :abbr
|
5
|
+
attribute :route_id
|
6
|
+
attribute :number, type: Integer
|
7
|
+
alias_method :id, :number
|
8
|
+
attribute :hexcolor
|
9
|
+
attribute :color
|
10
|
+
|
11
|
+
attribute :origin
|
12
|
+
attribute :destination
|
13
|
+
attribute :holidays
|
14
|
+
attribute :num_stns
|
15
|
+
attribute :direction
|
16
|
+
|
17
|
+
attribute :config
|
18
|
+
|
19
|
+
primary_attribute :id
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Bart
|
2
|
+
class Stop < Model
|
3
|
+
# Identity
|
4
|
+
attribute :name
|
5
|
+
attribute :abbr
|
6
|
+
attribute :link
|
7
|
+
|
8
|
+
# Location
|
9
|
+
attribute :gtfs_latitude, type: Float
|
10
|
+
alias_method :latitude, :gtfs_latitude
|
11
|
+
attribute :gtfs_longitude, type: Float
|
12
|
+
alias_method :longitude, :gtfs_longitude
|
13
|
+
attribute :address
|
14
|
+
attribute :city
|
15
|
+
attribute :county
|
16
|
+
attribute :state
|
17
|
+
attribute :zipcode
|
18
|
+
|
19
|
+
# Associations
|
20
|
+
attribute :north_routes
|
21
|
+
attribute :south_routes
|
22
|
+
attribute :north_platforms
|
23
|
+
attribute :south_platforms
|
24
|
+
|
25
|
+
# Prose metadata
|
26
|
+
attribute :platform_info
|
27
|
+
attribute :intro
|
28
|
+
attribute :cross_street
|
29
|
+
attribute :food
|
30
|
+
attribute :shopping
|
31
|
+
attribute :attraction
|
32
|
+
|
33
|
+
# Estimates from the `etd` endpoint
|
34
|
+
attribute :etd, type: Bart::Destination, array: true
|
35
|
+
alias_method :estimates, :etd
|
36
|
+
|
37
|
+
primary_attribute :abbr
|
38
|
+
alias_method :id, :abbr
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Bart
|
4
|
+
class Model
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
class << self
|
8
|
+
# Define a new attribute of the model.
|
9
|
+
# If `type` is given, a new instance of `type` will be created whenever
|
10
|
+
# this attribute is assigned a value. This allows creation of nested
|
11
|
+
# objects from a simple Hash.
|
12
|
+
# If `type` is given and `array` is true, the value given to this
|
13
|
+
# attribute will be interpreted as an array and a new instance of `type`
|
14
|
+
# will be created for each entry in the array
|
15
|
+
# It `type` is given, and the value given to this attribute is nil, no
|
16
|
+
# new instance of `type` will be created. Instead, the value will remain
|
17
|
+
# nil, as an instance of NilClass.
|
18
|
+
def attribute name, type: nil, array: false
|
19
|
+
attributes << [name, type]
|
20
|
+
attr_reader name
|
21
|
+
# Use a custom writer method to allow typed attributes to be
|
22
|
+
# instantiated properly.
|
23
|
+
define_method "#{name}=" do |value|
|
24
|
+
# Only do type conversion if the type is specified and the value is
|
25
|
+
# not nil.
|
26
|
+
if type and !value.nil?
|
27
|
+
# Lookup is done on Bart to ensure that Model subclasses are
|
28
|
+
# searched first, falling back to other types (Numeric, Hash, etc.)
|
29
|
+
# if no Model subclass is found.
|
30
|
+
klass = Bart.const_get(type.to_s)
|
31
|
+
value = array ? value.map{ |v| klass.new(v) } : klass.new(value)
|
32
|
+
end
|
33
|
+
instance_variable_set("@#{name}", value)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# The list of attributes defined on the model
|
38
|
+
def attributes
|
39
|
+
@attributes ||= Set.new
|
40
|
+
end
|
41
|
+
|
42
|
+
# The attribute of the model that can be used to uniquely identify an
|
43
|
+
# instance from any other. The primary attribute should also be set
|
44
|
+
# with `attribute <name>`.
|
45
|
+
attr_accessor :identifier
|
46
|
+
def primary_attribute name
|
47
|
+
@identifier = name
|
48
|
+
end
|
49
|
+
|
50
|
+
# Define one or more delegated methods on the model, passing them to the
|
51
|
+
# given attribute.
|
52
|
+
def delegate *names, to:
|
53
|
+
names.each do |name|
|
54
|
+
def_delegator to, name
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Initialize a model instance with any given attributes assigned
|
60
|
+
def initialize args={}
|
61
|
+
assign(args)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Mass assign a group of attributes. Attribute names will be automatically
|
65
|
+
# be converted to snake_case for consistency.
|
66
|
+
def assign args={}
|
67
|
+
args.each do |_name, value|
|
68
|
+
public_send("#{_name.underscore}=", value) if respond_to? "#{_name.underscore}="
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# The value of the primary attribute on this model
|
73
|
+
def identifier
|
74
|
+
send(self.class.identifier)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Assume that two Model objects are the same if their primary attributes
|
78
|
+
# have the same value
|
79
|
+
def == o
|
80
|
+
identifier == o.identifier
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Include all model subclasses
|
86
|
+
require_relative 'models/route'
|
87
|
+
require_relative 'models/arrival'
|
88
|
+
require_relative 'models/destination'
|
89
|
+
require_relative 'models/stop'
|
data/lib/bart_api.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'bart_api/core_ext/string'
|
2
|
+
require_relative 'bart_api/core_ext/hash'
|
3
|
+
require_relative 'bart_api/core_ext/float'
|
4
|
+
require_relative 'bart_api/core_ext/integer'
|
5
|
+
|
6
|
+
require_relative 'bart_api/version'
|
7
|
+
require_relative 'bart_api/configuration'
|
8
|
+
require_relative 'bart_api/connection'
|
9
|
+
require_relative 'bart_api/models'
|
10
|
+
require_relative 'bart_api/api'
|
11
|
+
require_relative 'bart_api/client'
|
12
|
+
|
13
|
+
module Bart
|
14
|
+
class << self
|
15
|
+
# Alias for `Bart::Client.new`
|
16
|
+
def new
|
17
|
+
Client.new
|
18
|
+
end
|
19
|
+
|
20
|
+
# The current client configuration
|
21
|
+
def configuration
|
22
|
+
@configuration ||= Configuration.new
|
23
|
+
end
|
24
|
+
|
25
|
+
# Allow users to set configuration options via a block. By default, the
|
26
|
+
# configuration will be validated after the block returns. This will raise
|
27
|
+
# an exception if any required configurations are not provided. This
|
28
|
+
# behavior can be skipped by passing `validate: false` as a parameter.
|
29
|
+
def configure validate: true
|
30
|
+
yield configuration
|
31
|
+
configuration.validate! if validate
|
32
|
+
configuration
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bart_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Elliott Williams
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-09-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.13'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: memoist
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.14'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.14'
|
41
|
+
description: A Ruby client for the BART real-time transit API.
|
42
|
+
email: code@elliottwillia.ms
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files:
|
46
|
+
- LICENSE
|
47
|
+
files:
|
48
|
+
- LICENSE
|
49
|
+
- lib/bart_api.rb
|
50
|
+
- lib/bart_api/api.rb
|
51
|
+
- lib/bart_api/client.rb
|
52
|
+
- lib/bart_api/client/estimates.rb
|
53
|
+
- lib/bart_api/client/routes.rb
|
54
|
+
- lib/bart_api/client/stops.rb
|
55
|
+
- lib/bart_api/configuration.rb
|
56
|
+
- lib/bart_api/connection.rb
|
57
|
+
- lib/bart_api/connection_adapters/httparty_adapter.rb
|
58
|
+
- lib/bart_api/core_ext/float.rb
|
59
|
+
- lib/bart_api/core_ext/hash.rb
|
60
|
+
- lib/bart_api/core_ext/integer.rb
|
61
|
+
- lib/bart_api/core_ext/string.rb
|
62
|
+
- lib/bart_api/models.rb
|
63
|
+
- lib/bart_api/models/arrival.rb
|
64
|
+
- lib/bart_api/models/destination.rb
|
65
|
+
- lib/bart_api/models/route.rb
|
66
|
+
- lib/bart_api/models/stop.rb
|
67
|
+
- lib/bart_api/version.rb
|
68
|
+
homepage: http://github.com/propershark/bart_api
|
69
|
+
licenses:
|
70
|
+
- MIT
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 2.2.0
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 2.6.9
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: A Ruby client for the BART real-time transit API.
|
92
|
+
test_files: []
|