bart_api 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/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: []
|