panda 0.5.0 → 0.6.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.
- data/README.md +5 -7
- data/Rakefile +1 -2
- data/VERSION +1 -1
- data/lib/panda/panda.rb +39 -12
- data/panda.gemspec +6 -9
- data/spec/panda_spec.rb +41 -15
- data/spec/spec_helper.rb +3 -2
- metadata +21 -53
data/README.md
CHANGED
@@ -8,6 +8,7 @@ Panda gem provides an interface to access the [Panda](http://pandastream.com) AP
|
|
8
8
|
|
9
9
|
## How to use it
|
10
10
|
|
11
|
+
require 'rubygems'
|
11
12
|
require 'panda'
|
12
13
|
|
13
14
|
### Creating an instance of the client
|
@@ -21,7 +22,7 @@ Panda gem provides an interface to access the [Panda](http://pandastream.com) AP
|
|
21
22
|
|
22
23
|
### Posting a video
|
23
24
|
|
24
|
-
Panda.post('/videos.json', {:file => File.
|
25
|
+
Panda.post('/videos.json', {:file => File.new("panda.mp4")}) # Note that you will need a movie file to test this. You can grab http://panda-test-harness-videos.s3.amazonaws.com/panda.mp4
|
25
26
|
|
26
27
|
Panda.post('/videos.json', {:source_url => 'http://www.example.com/original_video.mp4'})
|
27
28
|
=>{"duration"=>nil,
|
@@ -31,7 +32,6 @@ Panda gem provides an interface to access the [Panda](http://pandastream.com) AP
|
|
31
32
|
"source_url"=>"http://www.example.com/original_video.mp4",
|
32
33
|
"id"=>"12fce296-01e5-11df-ae37-12313902cc92",
|
33
34
|
"extname"=>".mp4",
|
34
|
-
"thumbnail_position"=>nil,
|
35
35
|
"audio_codec"=>nil,
|
36
36
|
"height"=>nil,
|
37
37
|
"upload_redirect_url"=>nil,
|
@@ -47,10 +47,9 @@ Panda gem provides an interface to access the [Panda](http://pandastream.com) AP
|
|
47
47
|
"created_at"=>"2010/01/13 16:45:29 +0000",
|
48
48
|
"original_filename"=>"panda.mp4",
|
49
49
|
"updated_at"=>"2010/01/13 16:45:35 +0000",
|
50
|
-
|
50
|
+
"source_url"=>"http://www.example.com/original_video.mp4",
|
51
51
|
"id"=>"0ee6b656-0063-11df-a433-1231390041c1",
|
52
52
|
"extname"=>".mp4",
|
53
|
-
"thumbnail_position"=>nil,
|
54
53
|
"audio_codec"=>"aac",
|
55
54
|
"height"=>240,
|
56
55
|
"upload_redirect_url"=>nil,
|
@@ -65,11 +64,10 @@ Panda gem provides an interface to access the [Panda](http://pandastream.com) AP
|
|
65
64
|
=> [{"encoder_id"=>nil,
|
66
65
|
"created_at"=>"2010/01/13 16:45:30 +0000",
|
67
66
|
"video_id"=>"0ee6b656-0063-11df-a433-1231390041c1",
|
68
|
-
"video_url"=>
|
69
|
-
|
67
|
+
"video_url"=>
|
68
|
+
"http://s3.amazonaws.com/panda-videos/0f815986-0063-11df-a433-1231390041c1.flv",
|
70
69
|
"started_encoding_at"=>"2010/01/13 16:47:35 +0000",
|
71
70
|
"updated_at"=>"2010/01/13 16:47:40 +0000",
|
72
|
-
"lock_version"=>7,
|
73
71
|
"extname"=>".flv",
|
74
72
|
"encoding_progress"=>87,
|
75
73
|
"encoding_time"=>3,
|
data/Rakefile
CHANGED
@@ -11,8 +11,7 @@ begin
|
|
11
11
|
gem.homepage = "http://github.com/newbamboo/panda_gem"
|
12
12
|
gem.authors = ["New Bamboo"]
|
13
13
|
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
-
gem.add_development_dependency "
|
15
|
-
gem.add_development_dependency "fakeweb-matcher"
|
14
|
+
gem.add_development_dependency "webmock"
|
16
15
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
16
|
gem.add_dependency "ruby-hmac", ">= 0.3.2"
|
18
17
|
gem.add_dependency "rest-client", ">= 1.5"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
data/lib/panda/panda.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'restclient'
|
2
|
+
require 'json'
|
2
3
|
|
3
4
|
class Panda
|
4
|
-
|
5
|
-
|
5
|
+
|
6
|
+
def self.connect!(auth_params, options={})
|
7
|
+
@@connection = Connection.new(auth_params, options)
|
6
8
|
end
|
7
9
|
|
8
10
|
def self.get(request_uri, params={})
|
@@ -44,23 +46,33 @@ class Panda
|
|
44
46
|
end
|
45
47
|
|
46
48
|
class Connection
|
47
|
-
attr_reader :api_host, :api_port, :access_key, :secret_key, :api_version
|
49
|
+
attr_reader :api_host, :api_port, :access_key, :secret_key, :api_version, :format
|
48
50
|
|
49
51
|
DEFAULT_API_PORT=80
|
50
52
|
DEFAULT_API_HOST="api.pandastream.com"
|
51
53
|
|
52
|
-
def initialize(auth_params)
|
54
|
+
def initialize(auth_params, options={})
|
53
55
|
@api_version = 2
|
54
|
-
|
56
|
+
@format = "hash"
|
57
|
+
|
55
58
|
if auth_params.class == String
|
59
|
+
self.format = options["format"]
|
56
60
|
init_from_url(auth_params)
|
57
61
|
else
|
62
|
+
self.format = auth_params["format"]
|
58
63
|
init_from_hash(auth_params)
|
59
64
|
end
|
60
|
-
|
65
|
+
|
61
66
|
@connection = RestClient::Resource.new(api_url)
|
62
67
|
end
|
63
68
|
|
69
|
+
def format=(ret_format)
|
70
|
+
if ret_format
|
71
|
+
raise "Format unknown" if !["json", "hash"].include?(ret_format.to_s)
|
72
|
+
@format = ret_format
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
64
76
|
def get(request_uri, params={})
|
65
77
|
rescue_restclient_exception do
|
66
78
|
query = signed_query("GET", request_uri, params)
|
@@ -92,7 +104,7 @@ class Panda
|
|
92
104
|
end
|
93
105
|
|
94
106
|
def signed_params(verb, request_uri, params = {}, timestamp_str = nil)
|
95
|
-
auth_params = params
|
107
|
+
auth_params = stringify_keys(params)
|
96
108
|
auth_params['cloud_id'] = @cloud_id
|
97
109
|
auth_params['access_key'] = @access_key
|
98
110
|
auth_params['timestamp'] = timestamp_str || Time.now.iso8601(6)
|
@@ -112,21 +124,36 @@ class Panda
|
|
112
124
|
end
|
113
125
|
|
114
126
|
private
|
115
|
-
|
127
|
+
def stringify_keys(params)
|
128
|
+
params.inject({}) do |options, (key, value)|
|
129
|
+
options[key.to_s] = value
|
130
|
+
options
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
116
134
|
def rescue_restclient_exception(&block)
|
117
135
|
begin
|
118
136
|
yield
|
119
137
|
rescue RestClient::Exception => e
|
120
|
-
e.http_body
|
138
|
+
format_to(e.http_body)
|
121
139
|
end
|
122
140
|
end
|
123
141
|
|
124
142
|
# API change on rest-client 1.4
|
125
143
|
def body_of(response)
|
126
|
-
response.respond_to?(:body) ? response.body : response
|
144
|
+
json_response = response.respond_to?(:body) ? response.body : response
|
145
|
+
format_to(json_response)
|
127
146
|
end
|
128
|
-
|
129
|
-
|
147
|
+
|
148
|
+
def format_to(response)
|
149
|
+
puts self.format
|
150
|
+
if self.format == "json"
|
151
|
+
return response
|
152
|
+
else
|
153
|
+
JSON.parse(response)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
130
157
|
def init_from_url(url)
|
131
158
|
params = url.scan(/http:\/\/([^:@]+):([^:@]+)@([^:@]+)(:[\d]+)?\/([^:@]+)$/).flatten
|
132
159
|
@access_key = params[0]
|
data/panda.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{panda}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["New Bamboo"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-06-08}
|
13
13
|
s.description = %q{Panda Client}
|
14
14
|
s.email = %q{info@pandastream.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.homepage = %q{http://github.com/newbamboo/panda_gem}
|
35
35
|
s.rdoc_options = ["--charset=UTF-8"]
|
36
36
|
s.require_paths = ["lib"]
|
37
|
-
s.rubygems_version = %q{1.3.
|
37
|
+
s.rubygems_version = %q{1.3.5}
|
38
38
|
s.summary = %q{Panda Client}
|
39
39
|
s.test_files = [
|
40
40
|
"spec/panda_spec.rb",
|
@@ -47,21 +47,18 @@ Gem::Specification.new do |s|
|
|
47
47
|
|
48
48
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
49
49
|
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
50
|
-
s.add_development_dependency(%q<
|
51
|
-
s.add_development_dependency(%q<fakeweb-matcher>, [">= 0"])
|
50
|
+
s.add_development_dependency(%q<webmock>, [">= 0"])
|
52
51
|
s.add_runtime_dependency(%q<ruby-hmac>, [">= 0.3.2"])
|
53
52
|
s.add_runtime_dependency(%q<rest-client>, [">= 1.5"])
|
54
53
|
else
|
55
54
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
56
|
-
s.add_dependency(%q<
|
57
|
-
s.add_dependency(%q<fakeweb-matcher>, [">= 0"])
|
55
|
+
s.add_dependency(%q<webmock>, [">= 0"])
|
58
56
|
s.add_dependency(%q<ruby-hmac>, [">= 0.3.2"])
|
59
57
|
s.add_dependency(%q<rest-client>, [">= 1.5"])
|
60
58
|
end
|
61
59
|
else
|
62
60
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
63
|
-
s.add_dependency(%q<
|
64
|
-
s.add_dependency(%q<fakeweb-matcher>, [">= 0"])
|
61
|
+
s.add_dependency(%q<webmock>, [">= 0"])
|
65
62
|
s.add_dependency(%q<ruby-hmac>, [">= 0.3.2"])
|
66
63
|
s.add_dependency(%q<rest-client>, [">= 1.5"])
|
67
64
|
end
|
data/spec/panda_spec.rb
CHANGED
@@ -2,7 +2,6 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe Panda do
|
4
4
|
before(:each) do
|
5
|
-
FakeWeb.allow_net_connect = false
|
6
5
|
Time.stub!(:now).and_return(mock("time", :iso8601 => "2009-11-04T17:54:11+00:00"))
|
7
6
|
end
|
8
7
|
|
@@ -21,16 +20,10 @@ describe Panda do
|
|
21
20
|
describe "Connected", :shared => true do
|
22
21
|
|
23
22
|
it "should make get request with signed request to panda server" do
|
24
|
-
|
23
|
+
stub_http_request(:get, "myapihost:85/v2/videos?timestamp=2009-11-04T17%3A54%3A11%2B00%3A00&signature=CxSYPM65SeeWH4CE%2FLcq7Ny2NtwxlpS8QOXG2BKe4p8%3D&access_key=my_access_key&cloud_id=my_cloud_id").to_return(:body => "abc")
|
25
24
|
@panda.get("/videos").should == "abc"
|
26
25
|
end
|
27
26
|
|
28
|
-
it "should make delete request with signed request to panda server" do
|
29
|
-
FakeWeb.register_uri(:delete, "http://myapihost:85/v2/videos/1?timestamp=2009-11-04T17%3A54%3A11%2B00%3A00&signature=t0IYclDXgjZFRYaMf0Gbg%2B5vOqp7q8QQRN8tlQ3bk8Q%3D&access_key=my_access_key&cloud_id=my_cloud_id", :query => {})
|
30
|
-
@panda.delete("/videos/1").should
|
31
|
-
FakeWeb.should have_requested(:delete, "http://myapihost:85/v2/videos/1?timestamp=2009-11-04T17%3A54%3A11%2B00%3A00&signature=t0IYclDXgjZFRYaMf0Gbg%2B5vOqp7q8QQRN8tlQ3bk8Q%3D&access_key=my_access_key&cloud_id=my_cloud_id")
|
32
|
-
end
|
33
|
-
|
34
27
|
it "should create a signed version of the parameters" do
|
35
28
|
signed_params = @panda.signed_params('POST',
|
36
29
|
'/videos.json',
|
@@ -70,10 +63,31 @@ describe Panda do
|
|
70
63
|
'space' => ' '
|
71
64
|
}
|
72
65
|
end
|
66
|
+
|
67
|
+
|
68
|
+
it "should not include file inside the signature" do
|
69
|
+
@panda.signed_params('POST', '/videos.json', { "file" => "my_file" }).should == {
|
70
|
+
'access_key' => "my_access_key",
|
71
|
+
'timestamp' => "2009-11-04T17:54:11+00:00",
|
72
|
+
'cloud_id' => 'my_cloud_id',
|
73
|
+
'signature' => 'TI2n/dsSllxFhxcEShRGKWtDSqxu+kuJUPs335NavMo=',
|
74
|
+
'file' => "my_file"
|
75
|
+
}
|
76
|
+
end
|
73
77
|
|
74
|
-
it "should
|
75
|
-
|
78
|
+
it "should stringify keys" do
|
79
|
+
@panda.signed_params('POST', '/videos.json', { :file => "symbol_key" }).should == {
|
80
|
+
'access_key' => "my_access_key",
|
81
|
+
'timestamp' => "2009-11-04T17:54:11+00:00",
|
82
|
+
'cloud_id' => 'my_cloud_id',
|
83
|
+
'signature' => 'TI2n/dsSllxFhxcEShRGKWtDSqxu+kuJUPs335NavMo=',
|
84
|
+
'file' => "symbol_key"
|
85
|
+
}
|
86
|
+
end
|
76
87
|
|
88
|
+
it "should return a json file for every http code" do
|
89
|
+
stub_http_request(:get, "http://myapihost:85/v2/videos?timestamp=2009-11-04T17%3A54%3A11%2B00%3A00&signature=CxSYPM65SeeWH4CE%2FLcq7Ny2NtwxlpS8QOXG2BKe4p8%3D&access_key=my_access_key&cloud_id=my_cloud_id").to_return(:body => "abc")
|
90
|
+
|
77
91
|
resource = RestClient::Resource.new("http://myapihost:85/v2")
|
78
92
|
RestClient::Resource.stub!(:new).and_return(resource)
|
79
93
|
|
@@ -89,7 +103,7 @@ describe Panda do
|
|
89
103
|
|
90
104
|
describe "Connected with a string url" do
|
91
105
|
before(:each) do
|
92
|
-
@panda = Panda::Connection.new('http://my_access_key:my_secret_key@myapihost:85/my_cloud_id')
|
106
|
+
@panda = Panda::Connection.new('http://my_access_key:my_secret_key@myapihost:85/my_cloud_id', "format" => "json")
|
93
107
|
end
|
94
108
|
|
95
109
|
it_should_behave_like "Connected"
|
@@ -97,15 +111,14 @@ describe Panda do
|
|
97
111
|
|
98
112
|
describe "Panda.connect " do
|
99
113
|
before(:each) do
|
100
|
-
Panda.connect!({"access_key" => "my_access_key", "secret_key" => "my_secret_key", "api_host" => "myapihost", "api_port" => 85, "cloud_id" => 'my_cloud_id' })
|
101
|
-
@panda = Panda
|
114
|
+
@panda = Panda.connect!({"access_key" => "my_access_key", "secret_key" => "my_secret_key", "api_host" => "myapihost", "api_port" => 85, "cloud_id" => 'my_cloud_id', "format" => "json" })
|
102
115
|
end
|
103
116
|
it_should_behave_like "Connected"
|
104
117
|
end
|
105
118
|
|
106
119
|
describe "Panda.connect with PANDASTREAM_URL" do
|
107
120
|
before(:each) do
|
108
|
-
Panda.connect!('http://my_access_key:my_secret_key@myapihost:85/my_cloud_id')
|
121
|
+
Panda.connect!('http://my_access_key:my_secret_key@myapihost:85/my_cloud_id', "format" => "json")
|
109
122
|
@panda = Panda
|
110
123
|
end
|
111
124
|
it_should_behave_like "Connected"
|
@@ -113,9 +126,22 @@ describe Panda do
|
|
113
126
|
|
114
127
|
describe "Panda::Connection.new" do
|
115
128
|
before(:each) do
|
116
|
-
@panda = Panda::Connection.new({"access_key" => "my_access_key", "secret_key" => "my_secret_key", "api_host" => "myapihost", "api_port" => 85, "cloud_id" => 'my_cloud_id' })
|
129
|
+
@panda = Panda::Connection.new({"access_key" => "my_access_key", "secret_key" => "my_secret_key", "api_host" => "myapihost", "api_port" => 85, "cloud_id" => 'my_cloud_id', "format" => "json" })
|
117
130
|
end
|
118
131
|
it_should_behave_like "Connected"
|
119
132
|
end
|
120
133
|
|
134
|
+
describe "Using hash as a return format" do
|
135
|
+
before(:each) do
|
136
|
+
@panda = Panda::Connection.new({"access_key" => "my_access_key", "secret_key" => "my_secret_key", "api_host" => "myapihost", "api_port" => 85, "cloud_id" => 'my_cloud_id' })
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should make get request" do
|
140
|
+
stub_http_request(:get, "myapihost:85/v2/videos?timestamp=2009-11-04T17%3A54%3A11%2B00%3A00&signature=CxSYPM65SeeWH4CE%2FLcq7Ny2NtwxlpS8QOXG2BKe4p8%3D&access_key=my_access_key&cloud_id=my_cloud_id").to_return(:body => "{\"key\":\"value\"}")
|
141
|
+
@panda.get("/videos").should == {'key' => 'value'}
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
|
121
147
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,12 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: panda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
segments:
|
6
|
-
- 0
|
7
|
-
- 5
|
8
|
-
- 0
|
9
|
-
version: 0.5.0
|
4
|
+
version: 0.6.0
|
10
5
|
platform: ruby
|
11
6
|
authors:
|
12
7
|
- New Bamboo
|
@@ -14,74 +9,49 @@ autorequire:
|
|
14
9
|
bindir: bin
|
15
10
|
cert_chain: []
|
16
11
|
|
17
|
-
date: 2010-
|
12
|
+
date: 2010-06-08 00:00:00 +01:00
|
18
13
|
default_executable:
|
19
14
|
dependencies:
|
20
15
|
- !ruby/object:Gem::Dependency
|
21
16
|
name: rspec
|
22
|
-
|
23
|
-
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
20
|
requirements:
|
25
21
|
- - ">="
|
26
22
|
- !ruby/object:Gem::Version
|
27
|
-
segments:
|
28
|
-
- 1
|
29
|
-
- 2
|
30
|
-
- 9
|
31
23
|
version: 1.2.9
|
32
|
-
|
33
|
-
version_requirements: *id001
|
24
|
+
version:
|
34
25
|
- !ruby/object:Gem::Dependency
|
35
|
-
name:
|
36
|
-
prerelease: false
|
37
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
-
requirements:
|
39
|
-
- - ">="
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
segments:
|
42
|
-
- 0
|
43
|
-
version: "0"
|
26
|
+
name: webmock
|
44
27
|
type: :development
|
45
|
-
|
46
|
-
|
47
|
-
name: fakeweb-matcher
|
48
|
-
prerelease: false
|
49
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
30
|
requirements:
|
51
31
|
- - ">="
|
52
32
|
- !ruby/object:Gem::Version
|
53
|
-
segments:
|
54
|
-
- 0
|
55
33
|
version: "0"
|
56
|
-
|
57
|
-
version_requirements: *id003
|
34
|
+
version:
|
58
35
|
- !ruby/object:Gem::Dependency
|
59
36
|
name: ruby-hmac
|
60
|
-
|
61
|
-
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
62
40
|
requirements:
|
63
41
|
- - ">="
|
64
42
|
- !ruby/object:Gem::Version
|
65
|
-
segments:
|
66
|
-
- 0
|
67
|
-
- 3
|
68
|
-
- 2
|
69
43
|
version: 0.3.2
|
70
|
-
|
71
|
-
version_requirements: *id004
|
44
|
+
version:
|
72
45
|
- !ruby/object:Gem::Dependency
|
73
46
|
name: rest-client
|
74
|
-
|
75
|
-
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
76
50
|
requirements:
|
77
51
|
- - ">="
|
78
52
|
- !ruby/object:Gem::Version
|
79
|
-
segments:
|
80
|
-
- 1
|
81
|
-
- 5
|
82
53
|
version: "1.5"
|
83
|
-
|
84
|
-
version_requirements: *id005
|
54
|
+
version:
|
85
55
|
description: Panda Client
|
86
56
|
email: info@pandastream.com
|
87
57
|
executables: []
|
@@ -118,20 +88,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
88
|
requirements:
|
119
89
|
- - ">="
|
120
90
|
- !ruby/object:Gem::Version
|
121
|
-
segments:
|
122
|
-
- 0
|
123
91
|
version: "0"
|
92
|
+
version:
|
124
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
94
|
requirements:
|
126
95
|
- - ">="
|
127
96
|
- !ruby/object:Gem::Version
|
128
|
-
segments:
|
129
|
-
- 0
|
130
97
|
version: "0"
|
98
|
+
version:
|
131
99
|
requirements: []
|
132
100
|
|
133
101
|
rubyforge_project:
|
134
|
-
rubygems_version: 1.3.
|
102
|
+
rubygems_version: 1.3.5
|
135
103
|
signing_key:
|
136
104
|
specification_version: 3
|
137
105
|
summary: Panda Client
|