zephyrus 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d767155594140e1d9015b8719daef8a282b9b923
4
+ data.tar.gz: 65da044b30406b4867358ea7ec5ce9cd8aa4e196
5
+ SHA512:
6
+ metadata.gz: b2ab7e5dee75cb06be4ab5e2068ea6c840c0f97d7f6645c4621c9894de45cc6f7116b2e7506e1804ba746818b9663e0dc48a589792debf099cd38975ece296a8
7
+ data.tar.gz: 72c9705d9e91e571f18c8198909803ebc514f1be962c9870b24a0d55f9119a5c7ee0454d6bdafbdff3c652b6e1751c9dd33f0270e6e38e80bf8cc9dd19fd5743
@@ -0,0 +1,49 @@
1
+ require 'singleton'
2
+
3
+ module Zephyrus
4
+
5
+ def self.configuration( &block )
6
+ Configuration.instance().instance_eval( &block ) unless block.nil?
7
+ Configuration.instance()
8
+ end
9
+
10
+ class Configuration
11
+
12
+ include Singleton
13
+
14
+ def self.reloadable?
15
+ false
16
+ end
17
+
18
+ def self.define_attribute( attribute_name, options = {} )
19
+
20
+ class_eval(
21
+ "def #{attribute_name}( *arguments ); " +
22
+ "@#{attribute_name} = arguments.first unless arguments.empty?; " +
23
+ "@#{attribute_name} || " +
24
+ ( options[ :default ].nil? ?
25
+ "nil" :
26
+ ( options[ :default ].is_a?( String ) ?
27
+ "'#{options[ :default ]}'" :
28
+ "#{options[ :default ]}" ) ) + ";" +
29
+ "end",
30
+ __FILE__,
31
+ __LINE__
32
+ )
33
+ end
34
+
35
+ # the api uri; DO NOT COMMIT A MODIFIED DEFAULT
36
+ define_attribute :api_uri, default: 'https://zephyrus.boxxspring.com'
37
+ define_attribute :api_credentials
38
+
39
+ def from_hash( configuration )
40
+
41
+ configuration.each_pair do | name, value |
42
+ self.instance_variable_set( "@#{name}", value )
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,147 @@
1
+ module Zephyrus
2
+
3
+ class Operation
4
+
5
+ def initialize( path, parameters = {} )
6
+ @path = path
7
+ @parameters = ( parameters || {} ).deep_dup
8
+ @key = nil
9
+ end
10
+
11
+ def key
12
+ return @key ||= begin
13
+ result = 0
14
+ query = @parameters.to_param
15
+ if ( @path.present? || @query.present? )
16
+ query = query.split( '&' ).sort.join( '&' )
17
+ addressable = Addressable::URI.new
18
+ addressable.path = @path
19
+ addressable.query = query unless query.blank?
20
+ result = FNV.new.fnv1a_32( addressable.to_s )
21
+ end
22
+ result
23
+ end
24
+ end
25
+
26
+ def where( parameters )
27
+ self.spawn( parameters )
28
+ end
29
+
30
+ def destroy
31
+ result = nil
32
+ Zephyrus::Request.new.tap do | request |
33
+ response = request.destroy( @path, @parameters )
34
+ if response.present?
35
+ result = response.resources
36
+ end
37
+ end
38
+ result
39
+ end
40
+
41
+ def order( by, direction = 'desc' )
42
+ self.spawn( sort_by: by, sort_direction: direction )
43
+ end
44
+
45
+ def limit( _limit )
46
+ self.spawn( count: _limit )
47
+ end
48
+
49
+ def offset( _offset )
50
+ self.spawn( offset: _offset )
51
+ end
52
+
53
+ def include( *arguments )
54
+ self.spawn( :include => self.normalize_include( *arguments ) )
55
+ end
56
+
57
+ def query( &block )
58
+ result = nil
59
+ Zephyrus::Request.new.tap do | request |
60
+ request.get( @path, @parameters ).tap do | response |
61
+ result = response.resources
62
+ if block_given?
63
+ case block.arity
64
+ when 0; yield
65
+ when 1; yield result
66
+ when 2; yield result, response
67
+ end
68
+ end
69
+ end
70
+ end
71
+ result
72
+ end
73
+
74
+ def read( &block )
75
+ response = nil
76
+ result = nil
77
+ self.query do | _result, _response |
78
+ result = _result
79
+ response = _response
80
+ end
81
+ if response.success?
82
+ result = result.first if result.present? && result.is_a?( Enumerable )
83
+ if block_given?
84
+ case block.arity
85
+ when 0; yield
86
+ when 1; yield result
87
+ when 2; yield result, response
88
+ end
89
+ end
90
+ end
91
+ result
92
+ end
93
+
94
+ def write( node, objects, &block )
95
+ result = nil
96
+ Zephyrus::Request.new.tap do | request |
97
+ serializer = Zephyrus::Serializer.new( objects )
98
+ response = request.post( @path, @parameters, serializer.serialize( node ) )
99
+ if response.present?
100
+ result = response.resources
101
+ if block_given?
102
+ case block.arity
103
+ when 0; yield
104
+ when 1; yield result
105
+ when 2; yield result, response
106
+ end
107
+ end
108
+ end
109
+ end
110
+ result
111
+ end
112
+
113
+ protected; def spawn( parameters )
114
+ Zephyrus::Operation.new(
115
+ @path,
116
+ @parameters.deep_merge( parameters || {} )
117
+ )
118
+ end
119
+
120
+ protected; def normalize_include( *arguments )
121
+
122
+ includes = {}
123
+ arguments.each do | argument |
124
+ case argument
125
+ when Array
126
+ argument.each do | value |
127
+ includes.deep_merge!( self.normalize_include( value ) )
128
+ end
129
+ when Hash
130
+ argument.each do | key, value |
131
+ if !includes.include?( key ) || includes[ key ] === true
132
+ includes[ key ] = self.normalize_include( value )
133
+ else
134
+ includes[ key ].deep_merge!( self.normalize_include( value ) )
135
+ end
136
+ end
137
+ else
138
+ includes[ argument ] = true
139
+ end
140
+ end
141
+ includes
142
+
143
+ end
144
+
145
+ end
146
+
147
+ end
@@ -0,0 +1,136 @@
1
+ module Zephyrus
2
+
3
+ class Parser
4
+
5
+ def initialize( content = {} )
6
+ @content = content
7
+ yield self if block_given?
8
+ end
9
+
10
+ def name
11
+ @content.include?( '$this' ) ?
12
+ @content[ '$this' ][ 'name' ] :
13
+ nil
14
+ end
15
+
16
+ def type_name
17
+ @content.include?( '$this' ) ?
18
+ @content[ '$this' ][ 'type_name' ] :
19
+ nil
20
+ end
21
+
22
+ def type_name?( name )
23
+ self.type_name == name.to_s
24
+ end
25
+
26
+ def key
27
+ 'id'
28
+ end
29
+
30
+ def keys
31
+ @content.include?( '$this' ) ?
32
+ @content[ '$this' ][ 'ids' ] :
33
+ nil
34
+ end
35
+
36
+ def associations
37
+ @content.include?( '$associations' ) ?
38
+ @content[ '$associations' ] :
39
+ nil
40
+ end
41
+
42
+ def resources
43
+ result = nil
44
+ unless self.name.blank?
45
+ result = self.keys.map do | key |
46
+ self.resource_by( name, key, { 'type_name' => self.type_name } )
47
+ end
48
+ end
49
+ result
50
+ end
51
+
52
+ def resource_by( name, key, options = {} )
53
+
54
+ @resources_index ||= Hash.new { | hash, key | hash[ key ] = {} }
55
+ @resource_index_mutex ||= Hash.new { | hash, key | hash[ key ] = [] }
56
+
57
+ @resources_index[ name ][ key ] ||= begin
58
+
59
+ # lock the resource index for this name/key combination
60
+ # note: this prevents zephyrus objects that are associated with
61
+ # themselves from causing a stack overflow
62
+ return nil if @resource_index_mutex[ name ].include?( key )
63
+ @resource_index_mutex[ name ].push( key )
64
+
65
+ result = nil
66
+ resource_attributes = resource_attribute_index[ name ][ key ]
67
+ if resource_attributes.present?
68
+ type_name = resource_attributes[ 'type_name' ]
69
+ klass = nil
70
+ klass = ( Zephyrus.const_get( type_name.camelize ) rescue nil ) \
71
+ if type_name.present?
72
+ if klass.nil?
73
+ type_name = options[ 'type_name' ]
74
+ klass = ( Zephyrus.const_get( type_name.camelize ) rescue nil ) \
75
+ if type_name.present?
76
+ end
77
+ if klass.present?
78
+ result = klass.new(
79
+ resource_attributes,
80
+ self.resource_associations_by( name, key )
81
+ )
82
+ end
83
+ end
84
+
85
+ # unlock the resource index for this name/key combination
86
+ @resource_index_mutex[ name ].delete( key )
87
+
88
+ result
89
+
90
+ end
91
+
92
+ end
93
+
94
+ def resource_associations_by( name, key )
95
+ result = Hash.new { | hash, key | hash[ key ] = [] }
96
+ associations = self.associations
97
+ if associations && associations.include?( name )
98
+ association = associations[ name ].detect do | association |
99
+ association[ 'id' ] == key
100
+ end
101
+ if association.present?
102
+ association.each do | key, value |
103
+ unless key == 'id'
104
+ type_name = value[ 'type_name' ]
105
+ result[ key ] = ( value[ 'ids' ] || [] ).map do | associated_id |
106
+ self.resource_by(
107
+ key,
108
+ associated_id,
109
+ { 'type_name' => type_name }
110
+ )
111
+ end
112
+ result[ key ].compact!
113
+ end
114
+ end
115
+ end
116
+ end
117
+ result
118
+ end
119
+
120
+ def resource_attribute_index
121
+ @resource_attribute_index ||= begin
122
+ index = Hash.new { | hash, key | hash[ key ] = {} }
123
+ @content.each do | key, resources_attributes |
124
+ unless key[0] == '$'
125
+ resources_attributes.each do | resource_attributes |
126
+ index[ key ][ resource_attributes[ 'id' ] ] = resource_attributes
127
+ end
128
+ end
129
+ end
130
+ index
131
+ end
132
+ end
133
+
134
+ end
135
+
136
+ end
@@ -0,0 +1,96 @@
1
+ require 'net/https'
2
+ require 'addressable/uri'
3
+
4
+ module Zephyrus
5
+
6
+ class Request
7
+
8
+ def initialize( default_parameters = {} )
9
+
10
+ # parse the API uri
11
+ uri = URI.parse( Zephyrus.configuration.api_uri )
12
+
13
+ # construct http request
14
+ @http = Net::HTTP.new( uri.host, uri.port )
15
+
16
+ # use ssl when https is the uri scheme
17
+ @http.use_ssl = ( uri.scheme == 'https' )
18
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
19
+
20
+ # retain the default parameters
21
+ @default_parameters = default_parameters.stringify_keys
22
+
23
+ end
24
+
25
+ def destroy( path, parameters = {} )
26
+
27
+ begin
28
+
29
+ request = Net::HTTP::Delete.new(
30
+ compose_request_path( path, parameters ),
31
+ { 'Content-Type' =>'application/json' }
32
+ )
33
+
34
+ response = Response.new( @http.request( request ) )
35
+
36
+ rescue Timeout::Error
37
+ response = nil
38
+ end
39
+
40
+ response
41
+
42
+ end
43
+
44
+ def get( path, parameters = {} )
45
+
46
+ response = nil
47
+
48
+ begin
49
+ response = Response.new(
50
+ @http.get( compose_request_path( path, parameters ) )
51
+ )
52
+ rescue Timeout::Error
53
+ response = nil
54
+ end
55
+
56
+ response
57
+
58
+ end
59
+
60
+ def post( path, parameters = {}, body = {} )
61
+
62
+ response = nil
63
+
64
+ begin
65
+
66
+ request = Net::HTTP::Post.new(
67
+ compose_request_path( path, parameters ),
68
+ { 'Content-Type' =>'application/json' }
69
+ )
70
+ request.body = body.to_json
71
+
72
+ response = Response.new( @http.request( request ) )
73
+
74
+ rescue Timeout::Error
75
+ response = nil
76
+ end
77
+
78
+ response
79
+
80
+ end
81
+
82
+ protected; def compose_request_path( path, parameters = {} )
83
+
84
+ parameters = @default_parameters.merge( parameters.stringify_keys )
85
+ addressable = Addressable::URI.new
86
+
87
+ addressable.path = path
88
+ addressable.query = parameters.to_param unless parameters.blank?
89
+
90
+ addressable.to_s
91
+
92
+ end
93
+
94
+ end
95
+
96
+ end
@@ -0,0 +1,7 @@
1
+ module Zephyrus
2
+
3
+ class AttributeError < Error
4
+ field :attribute
5
+ end
6
+
7
+ end
@@ -0,0 +1,67 @@
1
+ module Zephyrus
2
+
3
+ class Base
4
+
5
+ class << self
6
+
7
+ def inherited( subclass )
8
+ subclass.fields = {}.merge( self.fields )
9
+ end
10
+
11
+ def field( name, options = {} )
12
+
13
+ self.fields[ name.to_sym ] = options.merge( name: name )
14
+
15
+ class_eval(
16
+ "def #{name}(); " +
17
+ "@#{name}.is_a?( FalseClass ) ? @#{name} : (" +
18
+ "@#{name} || " +
19
+ ( options[ :default ].nil? ?
20
+ "nil" :
21
+ ( options[ :default ].is_a?( String ) ?
22
+ "'#{options[ :default ]}'" :
23
+ "#{options[ :default ]}" ) ) + ");" +
24
+ "end;" +
25
+ " " +
26
+ "attr_writer :#{name};",
27
+ __FILE__,
28
+ __LINE__
29
+ )
30
+
31
+ end
32
+
33
+ def has_one( name, options = {} )
34
+ define_method name do
35
+ associations = self.instance_variable_get( "@_#{name.to_s.pluralize}" )
36
+ associations.present? ? associations.first : options[ :default ]
37
+ end
38
+ end
39
+
40
+ def has_many( name, options = {} )
41
+ define_method name do
42
+ self.instance_variable_get( "@_#{name}" ) || options[ :default ] || []
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ class_attribute :fields, instance_writer: false
49
+ self.fields = {}
50
+
51
+ field :type_name
52
+ has_many :errors
53
+
54
+ def initialize( attributes = {}, associations = {} )
55
+ self.type_name = self.class.name.gsub( /Zephyrus::/, '' ).underscore
56
+ attributes.each do | key, value |
57
+ send( "#{key}=", value ) if respond_to?( "#{key}=" )
58
+ end
59
+ associations.each do | key, value |
60
+ self.instance_variable_set( "@_#{key}", value )
61
+ end
62
+ yield self if block_given?
63
+ end
64
+
65
+ end
66
+
67
+ end
@@ -0,0 +1,7 @@
1
+ module Zephyrus
2
+
3
+ class Error < Base
4
+ field :message
5
+ end
6
+
7
+ end
@@ -0,0 +1,6 @@
1
+ module Zephyrus
2
+
3
+ class ForbiddenError < Error
4
+ end
5
+
6
+ end
@@ -0,0 +1,13 @@
1
+ module Zephyrus
2
+ class Input < Base
3
+ field :id
4
+ field :created_at
5
+ field :updated_at
6
+ field :state
7
+ field :key
8
+ field :uid
9
+ field :uuid
10
+
11
+ has_many :outputs
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ module Zephyrus
2
+
3
+ class MalformedParameterError < Error
4
+ end
5
+
6
+ end
@@ -0,0 +1,6 @@
1
+ module Zephyrus
2
+
3
+ class MissingParameterError < Error
4
+ end
5
+
6
+ end
@@ -0,0 +1,6 @@
1
+ module Zephyrus
2
+
3
+ class NotFoundError < Error
4
+ end
5
+
6
+ end
@@ -0,0 +1,12 @@
1
+ module Zephyrus
2
+ class Output < Base
3
+ field :id
4
+ field :created_at
5
+ field :updated_at
6
+ field :key
7
+ field :uid
8
+ field :uuid
9
+ field :state
10
+ field :input_id
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+
2
+ module Zephyrus
3
+ class RecordingOutput < Output
4
+
5
+ field :recording
6
+ field :instance_id
7
+ field :last_recording_started_at
8
+
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Zephyrus
2
+ class RoutingOutput < Output
3
+
4
+ field :url
5
+ field :authentication_username
6
+ field :authentication_password
7
+
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+
2
+ module Zephyrus
3
+ class TranscodingOutput < Output
4
+
5
+ field :mime_type
6
+ field :video_bitrate
7
+ field :audio_bitrate
8
+ field :height
9
+ field :width
10
+ field :audio_sample_rate
11
+
12
+ end
13
+ end
@@ -0,0 +1,51 @@
1
+ module Zephyrus
2
+
3
+ class Response
4
+
5
+ attr_reader :code
6
+ attr_reader :body
7
+ attr_reader :resources
8
+
9
+ def initialize( http_response )
10
+
11
+ @success = http_response.is_a?( Net::HTTPOK )
12
+
13
+ @code = http_response.code
14
+ @resources = []
15
+
16
+ @body = decode_response_body( http_response )
17
+
18
+ if ( @body && @body.respond_to?( :keys ) )
19
+ Zephyrus::Parser.new( @body ) do | parser |
20
+ @resources = parser.resources
21
+ @success = !parser.type_name?( :error )
22
+ end
23
+ else
24
+ @success = false
25
+ @resources << Zephyrus::Error.new(
26
+ message: "#{@code}: #{http_response.message}."
27
+ )
28
+ end
29
+ end
30
+
31
+ def success?
32
+ @success
33
+ end
34
+
35
+ def failure?
36
+ not @success
37
+ end
38
+
39
+ protected; def decode_response_body( http_response )
40
+ body = http_response.body
41
+
42
+ if body.present?
43
+ JSON.parse( body ) rescue nil
44
+ else
45
+ nil
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,31 @@
1
+ module Zephyrus
2
+
3
+ class Serializer
4
+
5
+ def initialize( payload = [], options = {} )
6
+ @payload = [ payload ].flatten
7
+ @options = options
8
+ end
9
+
10
+ def serialize( node, options = {} )
11
+ result = {}
12
+ result[ node ] = @payload.map do | object |
13
+ node_object = {}
14
+ node_object[ :type_name ] = (
15
+ object.respond_to?( :type_name ) ?
16
+ object.type_name :
17
+ object.class.name.gsub( /Zephyrus::/, '' ).underscore
18
+ )
19
+ if object.respond_to?( :fields )
20
+ object.fields.each do | name, options |
21
+ node_object[ name.to_sym ] = object.send( name )
22
+ end
23
+ end
24
+ node_object
25
+ end
26
+ result
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,3 @@
1
+ module Zephyrus
2
+ VERSION = '0.1.0'
3
+ end
data/lib/zephyrus.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'active_support'
2
+ require 'active_support/all'
3
+ require 'fnv'
4
+
5
+ require 'zephyrus/configuration'
6
+ require 'zephyrus/response'
7
+ require 'zephyrus/request'
8
+ require 'zephyrus/parser'
9
+ require 'zephyrus/serializer'
10
+ require 'zephyrus/operation'
11
+
12
+ require 'zephyrus/resources/base'
13
+
14
+ # Errors
15
+ require 'zephyrus/resources/error'
16
+ require 'zephyrus/resources/forbidden_error'
17
+ require 'zephyrus/resources/attribute_error'
18
+ require 'zephyrus/resources/missing_parameter_error'
19
+ require 'zephyrus/resources/attribute_error'
20
+ require 'zephyrus/resources/malformed_parameter_error'
21
+ require 'zephyrus/resources/not_found_error'
22
+
23
+ # Resources
24
+ require 'zephyrus/resources/input'
25
+ require 'zephyrus/resources/output'
26
+ require 'zephyrus/resources/routing_output'
27
+ require 'zephyrus/resources/transcoding_output'
28
+ require 'zephyrus/resources/recording_output'
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zephyrus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Asher Kory
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: addressable
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: fnv
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.10.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.10.1
69
+ description: The zephyrus gem implements a client to the Sportsrocket Zephyrus API
70
+ email: asher@sportsrocket.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/zephyrus.rb
76
+ - lib/zephyrus/configuration.rb
77
+ - lib/zephyrus/operation.rb
78
+ - lib/zephyrus/parser.rb
79
+ - lib/zephyrus/request.rb
80
+ - lib/zephyrus/resources/attribute_error.rb
81
+ - lib/zephyrus/resources/base.rb
82
+ - lib/zephyrus/resources/error.rb
83
+ - lib/zephyrus/resources/forbidden_error.rb
84
+ - lib/zephyrus/resources/input.rb
85
+ - lib/zephyrus/resources/malformed_parameter_error.rb
86
+ - lib/zephyrus/resources/missing_parameter_error.rb
87
+ - lib/zephyrus/resources/not_found_error.rb
88
+ - lib/zephyrus/resources/output.rb
89
+ - lib/zephyrus/resources/recording_output.rb
90
+ - lib/zephyrus/resources/routing_output.rb
91
+ - lib/zephyrus/resources/transcoding_output.rb
92
+ - lib/zephyrus/response.rb
93
+ - lib/zephyrus/serializer.rb
94
+ - lib/zephyrus/version.rb
95
+ homepage: http://sportsrocket.com
96
+ licenses:
97
+ - MS-RL
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 2.6.8
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: Sportsrocket SDK for interacting with Zephyrus
119
+ test_files: []