bitsontherun 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ nbproject
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format
3
+ documentation
4
+ mtime
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :gemcutter
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ bitsontherun (0.0.1)
5
+ curb (= 0.7.10)
6
+ json (= 1.5.1)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ curb (0.7.10)
12
+ diff-lcs (1.1.2)
13
+ json (1.5.1)
14
+ rspec (2.4.0)
15
+ rspec-core (~> 2.4.0)
16
+ rspec-expectations (~> 2.4.0)
17
+ rspec-mocks (~> 2.4.0)
18
+ rspec-core (2.4.0)
19
+ rspec-expectations (2.4.0)
20
+ diff-lcs (~> 1.1.2)
21
+ rspec-mocks (2.4.0)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ bitsontherun!
28
+ bundler (= 1.0.10)
29
+ rspec (= 2.4.0)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Adrian Dulic
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.md ADDED
@@ -0,0 +1,78 @@
1
+ BitsOnTheRun
2
+ ==============
3
+
4
+ BitsOnTheRun is an implementation of [bitsontherun.com](bitsontherun.com) API in Ruby.
5
+
6
+ ## Install
7
+
8
+ Gemfile:
9
+
10
+ gem 'bitsontherun', :git => 'http://github.com/adriandulic/bitsontherun.git'
11
+
12
+ Setup:
13
+
14
+ BitsOnTheRun::Configuration.key = "your api key"
15
+ BitsOnTheRun::Configuration.secret = "your api secret"
16
+
17
+ ## Usage
18
+
19
+ Basic:
20
+
21
+ BitsOnTheRun::call('version') => {:status => "ok", :version => "X.X.X"}
22
+
23
+ BitsOnTheRun::store('videos/create', 'video.mp4') => {:status => "ok", ...}
24
+
25
+ BitsOnTheRun::call('videos/update', :video_key => 'your video key', :title => 'New title for video').ok? => true
26
+
27
+ Extended:
28
+
29
+ call = BitsOnTheRun::API.new(:call)
30
+ call.method('videos/list')
31
+ call.execute
32
+
33
+ call = BitsOnTheRun::API.new(:call)
34
+ call.method('videos/show', :video_key => 'your video key')
35
+ call.execute
36
+
37
+ call = BitsOnTheRun::API.new(:call)
38
+ call.method('videos/update', :video_key => 'your video key', :title => 'New title for video')
39
+ call.execute
40
+
41
+ call = BitsOnTheRun::API.new(:store)
42
+ call.method('videos/create')
43
+ call.file('video.mp4')
44
+ call.execute
45
+
46
+ ## How to navigate through response
47
+
48
+ Request:
49
+
50
+ BitsOnTheRun::call('accounts/show')
51
+
52
+ Response:
53
+
54
+ {:account => {:cdn => {:name => "Value" }}}
55
+
56
+ Find methods:
57
+
58
+ response.account.cdn.name => "Value"
59
+ response.account.cdn(:name) => "Value"
60
+ response.account(:cdn, :name) => "Value"
61
+ response.account([:cdn, :name]) => "Value"
62
+ response.find(:account, :cdn, :name) => "Value"
63
+ response.find([:account, :cdn, :name]) => "Value"
64
+
65
+
66
+ Request:
67
+
68
+ BitsOnTheRun::call('videos/list')
69
+
70
+ Response:
71
+
72
+ {:videos => [{ video }, { ... }, ...]}
73
+
74
+ Find methods:
75
+
76
+ response.videos => [<BitsOnTheRun::Response>, <BitsOnTheRun::Response>, ...]
77
+ response.videos.first => <BitsOnTheRun::Response>
78
+ repsonse.videos.first.title => "Video title"
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rspec"
5
+ require "rspec/core/rake_task"
6
+
7
+ Rspec::Core::RakeTask.new(:spec)
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/bitsontherun/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "bitsontherun"
6
+ s.version = BitsOnTheRun::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ['Adrian Dulic']
9
+ s.email = ['adulic@gmail.com']
10
+ s.homepage = "http://github.com/adriandulic/bitsontherun"
11
+ s.summary = "BitsOnTheRun.com API implementation in Ruby"
12
+ s.description = "BitsOnTheRun.com API implementation in Ruby"
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+ s.rubyforge_project = "bitsontherun"
16
+
17
+ s.add_dependency "json", "1.5.1"
18
+ s.add_dependency "curb", "0.7.10"
19
+
20
+ s.add_development_dependency "bundler", "1.0.10"
21
+ s.add_development_dependency "rspec", "2.4.0"
22
+
23
+ s.files = `git ls-files`.split("\n")
24
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
25
+ s.require_path = 'lib'
26
+ end
@@ -0,0 +1,64 @@
1
+ require 'curb'
2
+ require 'cgi'
3
+ require 'uri'
4
+
5
+ module BitsOnTheRun
6
+ PROTOCOL = "http"
7
+ URL = "api.bitsontherun.com"
8
+ API_VERSION = "v1"
9
+
10
+ autoload :API, "bitsontherun/api"
11
+ autoload :Configuration, "bitsontherun/configuration"
12
+ autoload :Call, "bitsontherun/call"
13
+ autoload :Store, "bitsontherun/store"
14
+ autoload :Response, "bitsontherun/response"
15
+ autoload :Parser, "bitsontherun/parser"
16
+
17
+ class Base
18
+ def initialize
19
+ @params = {}
20
+ end
21
+
22
+ def method(method, params = {})
23
+ @method = method.to_s
24
+ @params.merge!(params.to_hash)
25
+ end
26
+
27
+ protected
28
+ def build_url
29
+ URI.escape("#{PROTOCOL}://#{URL}/#{API_VERSION}/#{@method}?#{build_params}")
30
+ end
31
+
32
+ def build_params
33
+ @defaults.merge!(@params)
34
+ @defaults[:api_signature] = build_signature
35
+ escape_params
36
+ end
37
+
38
+ def build_signature
39
+ signature = escape_params
40
+ Digest::SHA1.hexdigest(signature + Configuration.secret)
41
+ end
42
+
43
+ def escape_params
44
+ params = @defaults.merge(@defaults) { |key, param| URI.escape(param.to_s) }
45
+ params = params.map { |key, param| "#{key}=#{param}"}
46
+ params.sort.join("&")
47
+ end
48
+ end
49
+
50
+ class << self
51
+ def call(method, params = {})
52
+ adapter = API.new(:call)
53
+ adapter.method(method, params)
54
+ adapter.execute
55
+ end
56
+
57
+ def store(method, filename, params = {})
58
+ adapter = API.new(:store)
59
+ adapter.method(method, params)
60
+ adapter.file(filename)
61
+ adapter.execute
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,28 @@
1
+ module BitsOnTheRun
2
+ class API
3
+ def initialize(adapter)
4
+ @adapter = BitsOnTheRun.const_get(adapter.to_s.capitalize).new
5
+ end
6
+
7
+ def method(method, params = {})
8
+ if params.include?(:api_format)
9
+ raise ArgumentError("Params hash should not include :api_format, use BitsOnTheRun::Configuration.format instead")
10
+ end
11
+ if params.include?(:api_key)
12
+ raise ArgumentError("Params hash should not include :api_key, use BitsOnTheRun::Configuration.key instead")
13
+ end
14
+ if params.include?(:api_secret)
15
+ raise ArgumentError("Params hash should not include :api_secret, use BitsOnTheRun::Configuration.secret instead")
16
+ end
17
+ @adapter.method(method, params)
18
+ end
19
+
20
+ def file(file)
21
+ @adapter.file(file)
22
+ end
23
+
24
+ def execute
25
+ @adapter.execute
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ require 'digest/sha1'
2
+ require 'net/http'
3
+
4
+ module BitsOnTheRun
5
+ class Call < Base
6
+ def initialize
7
+ @defaults = {
8
+ :api_nonce => "%08d" % rand(99999999),
9
+ :api_timestamp => Time.now.to_i,
10
+ :api_key => Configuration.key,
11
+ :api_format => Configuration.format,
12
+ :api_kit => "ruby-%s" % VERSION
13
+ }
14
+ super
15
+ end
16
+
17
+ def execute
18
+ response = Curl::Easy.perform(build_url).body_str
19
+ Response.new(response)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ module BitsOnTheRun
2
+ class Configuration
3
+ class << self
4
+ attr_accessor :key
5
+ attr_accessor :secret
6
+
7
+ def format; "json"; end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ require 'json'
2
+
3
+ module BitsOnTheRun
4
+ module Parser
5
+ extend self
6
+
7
+ def parse(response)
8
+ JSON.parse(response, :symbolize_names => true)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,58 @@
1
+ module BitsOnTheRun
2
+ class Response
3
+ def initialize(response, hash=false)
4
+ @response = response
5
+ if hash
6
+ @parsed = response
7
+ else
8
+ @parsed = Parser::parse(response)
9
+ end
10
+ end
11
+
12
+ def ok?
13
+ status == "ok"
14
+ end
15
+
16
+ def error?
17
+ status == "error"
18
+ end
19
+
20
+ def hash
21
+ to_hash
22
+ end
23
+
24
+ def to_hash
25
+ @parsed
26
+ end
27
+
28
+ def find(*args)
29
+ if args.first.class == Array
30
+ args = args.first
31
+ end
32
+ name = args.shift.to_sym
33
+ if @parsed.has_key?(name)
34
+ data = @parsed[name]
35
+ if args.first.class == Array
36
+ args = args.first
37
+ end
38
+ args.each do |arg|
39
+ data = data[arg]
40
+ end
41
+ if data.class == Hash
42
+ data = self.class.new(data, true)
43
+ end
44
+ if data.class == Array
45
+ data.map! { |d| self.class.new(d, true) }
46
+ end
47
+ data
48
+ else
49
+ nil
50
+ end
51
+ end
52
+
53
+ def method_missing(name, *args)
54
+ args.unshift(name)
55
+ find(*args)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,42 @@
1
+ module BitsOnTheRun
2
+ class Store < Base
3
+ def initialize
4
+ @response = nil
5
+ @defaults = {
6
+ :api_format => Configuration.format
7
+ }
8
+ super
9
+ end
10
+
11
+ def file(filename)
12
+ @filename = filename.to_s
13
+ end
14
+
15
+ def execute
16
+ build_token
17
+ file = Curl::PostField.file("file", @filename)
18
+ response = Curl::Easy.http_post(build_store_url, file) do |curl|
19
+ curl.multipart_form_post = true
20
+ end.body_str
21
+ Response.new(response)
22
+ end
23
+
24
+ private
25
+ def build_token
26
+ call = API.new(:call)
27
+ call.method(@method, @params)
28
+ @response = call.execute
29
+ end
30
+
31
+ def build_store_url
32
+ protocol = @response.find(:link, :protocol)
33
+ address = @response.find(:link, :address)
34
+ path = @response.find(:link, :path)
35
+
36
+ @defaults[:key] = @response.find(:link, :query, :key)
37
+ @defaults[:token] = @response.find(:link, :query, :token)
38
+
39
+ URI.escape("#{protocol}://#{address}#{path}?#{escape_params}")
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ module BitsOnTheRun
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe "API call to retrieve account" do
4
+ it_should_behave_like "Successful response"
5
+
6
+ before do
7
+ @responses = []
8
+ @responses << BitsOnTheRun::call('accounts/show', :account_key => BitsOnTheRun::Configuration.key)
9
+
10
+ @manual = BitsOnTheRun::API.new(:call)
11
+ @manual.method('accounts/show', :account_key => BitsOnTheRun::Configuration.key)
12
+ @responses << @manual.execute
13
+ end
14
+
15
+ it "should contain information about specific account" do
16
+ @responses.each do |r|
17
+ r.find(:account, :cdn, :name).should be_instance_of String
18
+ r.find([:account, :cdn, :name]).should be_instance_of String
19
+ r.find(:account, [:cdn, :name]).should be_instance_of String
20
+ r.account(:cdn, :name).should be_instance_of String
21
+ r.account([:cdn, :name]).should be_instance_of String
22
+ r.account.cdn(:name).should be_instance_of String
23
+ r.account.cdn.name.should be_instance_of String
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Configuration" do
4
+ before do
5
+ @key = BitsOnTheRun::Configuration.key
6
+ @secret = BitsOnTheRun::Configuration.secret
7
+ end
8
+
9
+ it "should store configuration information in class attributes" do
10
+ BitsOnTheRun::Configuration.key = "your api key"
11
+ BitsOnTheRun::Configuration.secret = "your api secret"
12
+
13
+ BitsOnTheRun::Configuration.key.should == "your api key"
14
+ BitsOnTheRun::Configuration.secret.should == "your api secret"
15
+ BitsOnTheRun::Configuration.format.should == "json"
16
+ end
17
+
18
+ after do
19
+ BitsOnTheRun::Configuration.key = @key
20
+ BitsOnTheRun::Configuration.secret = @secret
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe "API call to delete video files" do
4
+ it_should_behave_like "Successful response"
5
+
6
+ before do
7
+ @video = BitsOnTheRun::store('videos/create', 'spec/test.mp4')
8
+ @responses = BitsOnTheRun::call('videos/delete', :video_key => @video.media.key)
9
+ end
10
+
11
+ it "should contain confirmation about deleted video" do
12
+ @responses.each do |r|
13
+ r.ok?.should be_true
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe "API call to non existent resource" do
4
+ it_should_behave_like "Error response"
5
+
6
+ before do
7
+ @responses = []
8
+ @responses << BitsOnTheRun::call('videos/show', :video_key => 'wrong key here')
9
+ end
10
+
11
+ it "should contain information about error" do
12
+ @responses.each do |r|
13
+ r.video
14
+ r.code.should eql("NotFound")
15
+ r.title.should eql("Not Found")
16
+ r.message.should eql("video_key: Video with the key wrong key here does not exist")
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Response JSON parser" do
4
+ before do
5
+ @json = '{"status": "ok", "other": {"name": "Valid"}}'
6
+ end
7
+
8
+ it "should parse JSON string to Hash" do
9
+ output = BitsOnTheRun::Parser.parse(@json)
10
+ output.should be_instance_of Hash
11
+ output.should have_key :status
12
+ output.should have_key :other
13
+ output[:status].should eql("ok")
14
+ output[:other].should have_key :name
15
+ output[:other][:name].should eql("Valid")
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe "API call to store new video file" do
4
+ it_should_behave_like "Successful response"
5
+
6
+ before do
7
+ @responses = []
8
+ @file = 'spec/test.mp4'
9
+ @responses << BitsOnTheRun::store('videos/create', @file)
10
+
11
+ @manual = BitsOnTheRun::API.new(:store)
12
+ @manual.method('videos/create')
13
+ @manual.file(@file)
14
+ @responses << @manual.execute
15
+ end
16
+
17
+ it "should contain information about uploaded video" do
18
+ @responses.each do |r|
19
+ r.file(:md5).size.should eql(32)
20
+ r.file(:size).to_i.should > 0
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe "API call to retrieve version" do
4
+ it_should_behave_like "Successful response"
5
+
6
+ before do
7
+ @responses = []
8
+ @responses << BitsOnTheRun::call('version')
9
+ end
10
+
11
+ it "should contain information about API current version" do
12
+ @responses.each do |r|
13
+ r.version.should be_instance_of String
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for "Successful response" do
4
+ it "should contain status attribute with value #ok" do
5
+ @responses.each do |r|
6
+ r.status.should eql("ok")
7
+ r.ok?.should be_true
8
+ r.error?.should be_false
9
+ end
10
+ end
11
+ end
12
+
13
+ shared_examples_for "Error response" do
14
+ it "should contain status attribute with value #error" do
15
+ @responses.each do |r|
16
+ r.status.should eql("error")
17
+ r.ok?.should be_false
18
+ r.error?.should be_true
19
+ r.code.should_not be_nil
20
+ r.title.should_not be_nil
21
+ r.message.should_not be_nil
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ require 'rspec'
2
+ require 'bitsontherun'
3
+ require 'shared_specs'
4
+
5
+ Rspec.configure do |c|
6
+ c.mock_with :rspec
7
+ end
8
+
9
+ BitsOnTheRun::Configuration.key = "your api key"
10
+ BitsOnTheRun::Configuration.secret = "your api secret"
11
+
data/spec/test.mp4 ADDED
Binary file
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bitsontherun
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Adrian Dulic
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-07 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: json
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - "="
28
+ - !ruby/object:Gem::Version
29
+ hash: 1
30
+ segments:
31
+ - 1
32
+ - 5
33
+ - 1
34
+ version: 1.5.1
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: curb
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - "="
44
+ - !ruby/object:Gem::Version
45
+ hash: 23
46
+ segments:
47
+ - 0
48
+ - 7
49
+ - 10
50
+ version: 0.7.10
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: bundler
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - "="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 1
64
+ - 0
65
+ - 10
66
+ version: 1.0.10
67
+ type: :development
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - "="
76
+ - !ruby/object:Gem::Version
77
+ hash: 31
78
+ segments:
79
+ - 2
80
+ - 4
81
+ - 0
82
+ version: 2.4.0
83
+ type: :development
84
+ version_requirements: *id004
85
+ description: BitsOnTheRun.com API implementation in Ruby
86
+ email:
87
+ - adulic@gmail.com
88
+ executables: []
89
+
90
+ extensions: []
91
+
92
+ extra_rdoc_files: []
93
+
94
+ files:
95
+ - .gitignore
96
+ - .rspec
97
+ - Gemfile
98
+ - Gemfile.lock
99
+ - LICENSE
100
+ - README.md
101
+ - Rakefile
102
+ - bitsontherun.gemspec
103
+ - lib/bitsontherun.rb
104
+ - lib/bitsontherun/api.rb
105
+ - lib/bitsontherun/call.rb
106
+ - lib/bitsontherun/configuration.rb
107
+ - lib/bitsontherun/parser.rb
108
+ - lib/bitsontherun/response.rb
109
+ - lib/bitsontherun/store.rb
110
+ - lib/bitsontherun/version.rb
111
+ - spec/lib/account_spec.rb
112
+ - spec/lib/configuration_spec.rb
113
+ - spec/lib/delete_spec.rb
114
+ - spec/lib/error_spec.rb
115
+ - spec/lib/parse_spec.rb
116
+ - spec/lib/store_spec.rb
117
+ - spec/lib/version_spec.rb
118
+ - spec/shared_specs.rb
119
+ - spec/spec_helper.rb
120
+ - spec/test.mp4
121
+ has_rdoc: true
122
+ homepage: http://github.com/adriandulic/bitsontherun
123
+ licenses: []
124
+
125
+ post_install_message:
126
+ rdoc_options: []
127
+
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ hash: 3
136
+ segments:
137
+ - 0
138
+ version: "0"
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ hash: 23
145
+ segments:
146
+ - 1
147
+ - 3
148
+ - 6
149
+ version: 1.3.6
150
+ requirements: []
151
+
152
+ rubyforge_project: bitsontherun
153
+ rubygems_version: 1.5.0
154
+ signing_key:
155
+ specification_version: 3
156
+ summary: BitsOnTheRun.com API implementation in Ruby
157
+ test_files: []
158
+