panda 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/{spec/spec.opts → .rspec} +0 -0
- data/CHANGELOG.md +52 -0
- data/Gemfile +2 -14
- data/README.md +38 -32
- data/Rakefile +9 -27
- data/lib/panda.rb +9 -3
- data/lib/panda/adapters/adapter.rb +4 -0
- data/lib/panda/adapters/faraday.rb +70 -0
- data/lib/panda/adapters/restclient.rb +67 -0
- data/lib/panda/api_authentication.rb +2 -0
- data/lib/panda/base.rb +23 -21
- data/lib/panda/config.rb +58 -0
- data/lib/panda/connection.rb +33 -122
- data/lib/panda/errors.rb +17 -0
- data/lib/panda/modules/builders.rb +18 -10
- data/lib/panda/modules/destroyers.rb +25 -0
- data/lib/panda/modules/finders.rb +10 -4
- data/lib/panda/modules/router.rb +16 -10
- data/lib/panda/modules/updatable.rb +3 -2
- data/lib/panda/modules/video_state.rb +16 -0
- data/lib/panda/modules/viewable.rb +19 -0
- data/lib/panda/panda.rb +41 -20
- data/lib/panda/proxies/proxy.rb +3 -1
- data/lib/panda/proxies/scope.rb +34 -28
- data/lib/panda/resources/cloud.rb +13 -11
- data/lib/panda/resources/encoding.rb +4 -19
- data/lib/panda/resources/resource.rb +2 -12
- data/lib/panda/resources/video.rb +4 -1
- data/lib/panda/version.rb +3 -0
- data/panda.gemspec +22 -105
- data/spec/cloud_spec.rb +44 -35
- data/spec/encoding_spec.rb +28 -9
- data/spec/heroku_spec.rb +15 -5
- data/spec/panda_spec.rb +41 -68
- data/spec/profile_spec.rb +6 -6
- data/spec/spec_helper.rb +3 -4
- data/spec/video_spec.rb +68 -19
- metadata +44 -98
- data/VERSION +0 -1
- data/lib/panda/error.rb +0 -29
- data/lib/panda/modules/short_status.rb +0 -13
data/.gitignore
ADDED
data/{spec/spec.opts → .rspec}
RENAMED
File without changes
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
## 1.4.0 (...)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- Replaced Restclient/json by Faraday/Yajl
|
6
|
+
- Added Cloud.create, Cloud.all
|
7
|
+
- Https support for heroku account
|
8
|
+
- Simpler heroku configure method
|
9
|
+
- Simpler configure method
|
10
|
+
- Url and screenshots method for video
|
11
|
+
- `create` method accepts a block
|
12
|
+
- Removed support for JSON format
|
13
|
+
|
14
|
+
Bugfixes:
|
15
|
+
- timestamp is UTC
|
16
|
+
- `to_json` method
|
17
|
+
- `create!` on associations was wrong
|
18
|
+
|
19
|
+
## 1.3.0 (January 10, 2011)
|
20
|
+
|
21
|
+
Features:
|
22
|
+
|
23
|
+
- Added support for https
|
24
|
+
|
25
|
+
## 1.2.2 (December 08, 2010)
|
26
|
+
|
27
|
+
Bugfixes:
|
28
|
+
|
29
|
+
- No more warnings about already initialized constants for JSON
|
30
|
+
|
31
|
+
## 1.2.0 (November 25, 2010)
|
32
|
+
|
33
|
+
Features:
|
34
|
+
|
35
|
+
- Added support for the notification api.
|
36
|
+
- Added support for path and url
|
37
|
+
|
38
|
+
## 1.1.0 (October 19, 2010)
|
39
|
+
|
40
|
+
Bugfixes:
|
41
|
+
|
42
|
+
- Do not cache screenshot array anymore
|
43
|
+
|
44
|
+
## 1.0.0 (August 05, 2010)
|
45
|
+
|
46
|
+
- Simpler and smarter gem
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
August 05, 2010
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -15,30 +15,32 @@ Panda gem provides an interface to access the [Panda](http://pandastream.com) AP
|
|
15
15
|
|
16
16
|
### Creating an instance of the client
|
17
17
|
|
18
|
-
Panda.configure do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
#
|
23
|
-
#
|
18
|
+
Panda.configure do
|
19
|
+
access_key "panda_access_key"
|
20
|
+
secret_key "panda_secret_key"
|
21
|
+
cloud_id "panda_cloud_id"
|
22
|
+
# api_host "api.eu.pandastream.com" ## for EU accounts
|
23
|
+
# api_port 80 ## to use http (default 443)
|
24
24
|
end
|
25
25
|
|
26
26
|
or Panda.configure({:access_key => ....})
|
27
27
|
|
28
|
-
###
|
28
|
+
### Inside a Rails app with a main account or using Heroku Addon
|
29
29
|
|
30
|
-
|
30
|
+
Heroku will store your credentials as an environment variable called PANDASTREAM_URL. You can find more information on [Heroku config variable docs](http://docs.heroku.com/config-vars)
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
Config is stored in `config/panda.yml` or you must set an the PANDASTREAM_URL environment variable in your `/.bashrc` file (see the [Heroku config variable docs](http://docs.heroku.com/config-vars)).
|
35
|
-
|
36
|
-
Use the following in your `config/initializers/panda.rb`:
|
32
|
+
If you use a config file like `config/panda.yml` to support multiple environments, do the following in your `config/initializers/panda.rb` :
|
37
33
|
|
38
34
|
Panda.configure((ENV['PANDASTREAM_URL'] || YAML::load_file(File.join(File.dirname(__FILE__),"..", "panda.yml"))[RAILS_ENV]))
|
39
35
|
|
40
36
|
See the [Rails How-to](http://www.pandastream.com/docs/integrate_with_rails) for more details.
|
41
37
|
|
38
|
+
### Creating an instance using ONLY with Heroku Addon
|
39
|
+
|
40
|
+
If you don't use a config file and want to simply be setup, do the following (works only on heroku):
|
41
|
+
|
42
|
+
Panda.configure_heroku
|
43
|
+
|
42
44
|
### Typical usage
|
43
45
|
|
44
46
|
In most cases you will have used the [panda\_uploader](http://github.com/newbamboo/panda_uploader) jQuery plugin to upload the video (more details about this are in the [Integrating Panda with Ruby on Rails](http://pandastream.com/docs/integrate_with_rails) tutorial). Then you will want to get the video and screenshots urls of your encoding to display to your users.
|
@@ -346,7 +348,27 @@ The name of the profile can be found in your [Panda account](http://pandastream.
|
|
346
348
|
or
|
347
349
|
profile.encodings.all(:status => "success")
|
348
350
|
=> [...]
|
349
|
-
|
351
|
+
|
352
|
+
### Clouds
|
353
|
+
|
354
|
+
#### Find a cloud
|
355
|
+
|
356
|
+
cloud = Panda::Cloud.find(234324)
|
357
|
+
cloud.id
|
358
|
+
=> 234324
|
359
|
+
|
360
|
+
##### Find all clouds
|
361
|
+
|
362
|
+
clouds = Panda::Cloud.all
|
363
|
+
clouds.size
|
364
|
+
=> 2
|
365
|
+
|
366
|
+
##### Create a cloud
|
367
|
+
|
368
|
+
cloud = Panda::Cloud.create :aws_access_key => 'mys3key', :aws_secret_key => 'mys3secret', :s3_videos_bucket => 'myexistingbucket'
|
369
|
+
cloud.id
|
370
|
+
=> 1234
|
371
|
+
|
350
372
|
### Using multiple clouds
|
351
373
|
|
352
374
|
By default Cloud.id uses options defined with: Panda.configure do .. end
|
@@ -368,17 +390,13 @@ The name of the profile can be found in your [Panda account](http://pandastream.
|
|
368
390
|
cloud_two.profiles
|
369
391
|
cloud_two.profiles.create(:preset_name => "h264")
|
370
392
|
cloud_one.videos.create(:command => "ffmpeg -i $input_file$ -y $output_file$", ....)
|
371
|
-
|
372
|
-
You can also connect directly using Cloud.find
|
373
|
-
|
374
|
-
cloud = Panda::Cloud.find("cloud_id_1", {:access_key => ..., :secret_key => ... })
|
375
393
|
|
376
394
|
|
377
395
|
## Generating signatures
|
378
396
|
|
379
|
-
|
397
|
+
All requests to your Panda cloud are signed using HMAC-SHA256, based on a timestamp and your Panda secret key. This is handled transparently. However, sometimes you will want to generate only this signature, in order to make a request by means other than this library. This is the case when using the [JavaScript panda_uploader](http://github.com/newbamboo/panda_uploader).
|
380
398
|
|
381
|
-
|
399
|
+
To do this, a method `signed_params()` is supported:
|
382
400
|
|
383
401
|
Panda.signed_params('POST', '/videos.json')
|
384
402
|
# => {'access_key' => '8df50af4-074f-11df-b278-1231350015b1',
|
@@ -469,21 +487,9 @@ The name of the profile can be found in your [Panda account](http://pandastream.
|
|
469
487
|
|
470
488
|
Panda.delete('/videos/0ee6b656-0063-11df-a433-1231390041c1.json')
|
471
489
|
|
472
|
-
## Hash or JSON
|
473
|
-
Since Panda 0.6, PandaGem returns a Hash by default. If you want PandaGem to return JSON do the following:
|
474
|
-
|
475
|
-
Panda.connect!({
|
476
|
-
:cloud_id => 'cloud_id',
|
477
|
-
:access_key => 'access_key',
|
478
|
-
:secret_key => 'secret_key',
|
479
|
-
:format => 'json'
|
480
|
-
})
|
481
|
-
|
482
|
-
|
483
490
|
## Use bundler to setup the test environment (1.0)
|
484
491
|
|
485
492
|
bundler install
|
486
493
|
rake spec
|
487
494
|
|
488
|
-
|
489
495
|
Copyright (c) 2009-2010 New Bamboo. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -1,27 +1,9 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
gem.email = "info@pandastream.com"
|
11
|
-
gem.homepage = "http://github.com/newbamboo/panda_gem"
|
12
|
-
gem.authors = ["New Bamboo"]
|
13
|
-
gem.add_dependency "ruby-hmac", ">= 0.3.2"
|
14
|
-
gem.add_dependency "rest-client", ">= 1.4"
|
15
|
-
gem.add_dependency "json", ">= 1.2"
|
16
|
-
end
|
17
|
-
Jeweler::GemcutterTasks.new
|
18
|
-
rescue LoadError
|
19
|
-
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
20
|
-
end
|
21
|
-
|
22
|
-
desc "Run all the specs"
|
23
|
-
task :spec do
|
24
|
-
system "bundle exec spec -O spec/spec.opts spec"
|
25
|
-
end
|
26
|
-
|
27
|
-
task :default => :spec
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
desc "Run all the specs"
|
5
|
+
task :spec do
|
6
|
+
system "bundle exec rspec spec"
|
7
|
+
end
|
8
|
+
|
9
|
+
task :default => :spec
|
data/lib/panda.rb
CHANGED
@@ -1,22 +1,28 @@
|
|
1
|
+
require 'panda/version'
|
1
2
|
require 'panda/api_authentication'
|
2
3
|
require 'panda/connection'
|
4
|
+
require 'panda/config'
|
3
5
|
require 'panda/modules/router'
|
4
6
|
require 'panda/modules/finders'
|
5
7
|
require 'panda/modules/builders'
|
8
|
+
require 'panda/modules/destroyers'
|
6
9
|
require 'panda/modules/associations'
|
7
10
|
require 'panda/modules/updatable'
|
8
|
-
require 'panda/modules/
|
11
|
+
require 'panda/modules/viewable'
|
12
|
+
require 'panda/modules/video_state'
|
9
13
|
require 'panda/modules/cloud_connection'
|
10
14
|
require 'panda/proxies/proxy'
|
11
15
|
require 'panda/proxies/scope'
|
12
16
|
require 'panda/proxies/encoding_scope'
|
13
17
|
require 'panda/proxies/video_scope'
|
14
18
|
require 'panda/proxies/profile_scope'
|
15
|
-
require 'panda/
|
19
|
+
require 'panda/adapters/adapter'
|
20
|
+
require 'panda/adapters/faraday'
|
21
|
+
require 'panda/errors'
|
16
22
|
require 'panda/base'
|
17
23
|
require 'panda/resources/resource'
|
18
24
|
require 'panda/resources/cloud'
|
19
25
|
require 'panda/resources/encoding'
|
20
26
|
require 'panda/resources/profile'
|
21
27
|
require 'panda/resources/video'
|
22
|
-
require 'panda/panda'
|
28
|
+
require 'panda/panda'
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'yajl/json_gem'
|
3
|
+
|
4
|
+
module Panda
|
5
|
+
module Adapter
|
6
|
+
class Faraday
|
7
|
+
|
8
|
+
def initialize(api_url)
|
9
|
+
@api_url = api_url
|
10
|
+
end
|
11
|
+
|
12
|
+
def get(request_uri, params)
|
13
|
+
rescue_json_parsing do
|
14
|
+
response = connection.get do |req|
|
15
|
+
req.url File.join(connection.path_prefix, request_uri), params
|
16
|
+
end.body
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def post(request_uri, params)
|
21
|
+
# multipart upload
|
22
|
+
if (f=params['file']) && f.is_a?(File)
|
23
|
+
params['file'] = ::Faraday::UploadIO.new(f.path, 'multipart/form-data')
|
24
|
+
end
|
25
|
+
|
26
|
+
rescue_json_parsing do
|
27
|
+
connection.post do |req|
|
28
|
+
req.url File.join(connection.path_prefix, request_uri)
|
29
|
+
req.body = params
|
30
|
+
end.body
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def put(request_uri, params)
|
35
|
+
rescue_json_parsing do
|
36
|
+
connection.put do |req|
|
37
|
+
req.url File.join(connection.path_prefix, request_uri)
|
38
|
+
req.body = params
|
39
|
+
end.body
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(request_uri, params)
|
44
|
+
rescue_json_parsing do
|
45
|
+
connection.delete do |req|
|
46
|
+
req.url File.join(connection.path_prefix, request_uri), params
|
47
|
+
end.body
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def connection
|
54
|
+
@conn ||= ::Faraday::Connection.new(:url => @api_url) do |builder|
|
55
|
+
builder.adapter :net_http
|
56
|
+
builder.response :yajl
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def rescue_json_parsing(&block)
|
61
|
+
begin
|
62
|
+
yield || raise(ServiceNotAvailable)
|
63
|
+
rescue ::Faraday::Error::ParsingError => e
|
64
|
+
raise(ServiceNotAvailable)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'restclient'
|
2
|
+
require 'json' unless defined?(ActiveSupport::JSON) || defined?(JSON::JSON_LOADED)
|
3
|
+
|
4
|
+
module Panda
|
5
|
+
module Adapter
|
6
|
+
class RestClient
|
7
|
+
|
8
|
+
def initialize(api_url)
|
9
|
+
@api_url = api_url
|
10
|
+
end
|
11
|
+
|
12
|
+
def get(request_uri, params)
|
13
|
+
rescue_json_parsing do
|
14
|
+
query = ApiAuthentication.hash_to_query(params)
|
15
|
+
hash_response connection[request_uri + '?' + query].get
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def post(request_uri, params)
|
20
|
+
rescue_json_parsing do
|
21
|
+
hash_response connection[request_uri].post(params)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def put(request_uri, params)
|
26
|
+
rescue_json_parsing do
|
27
|
+
hash_response connection[request_uri].put(params)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def delete(request_uri, params)
|
32
|
+
rescue_json_parsing do
|
33
|
+
query = ApiAuthentication.hash_to_query(params)
|
34
|
+
hash_response connection[request_uri + '?' + query].delete
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def connection
|
41
|
+
@conn ||= ::RestClient::Resource.new(@api_url)
|
42
|
+
end
|
43
|
+
|
44
|
+
def hash_response(response)
|
45
|
+
begin
|
46
|
+
if defined?(ActiveSupport::JSON)
|
47
|
+
ActiveSupport::JSON.decode(response)
|
48
|
+
else
|
49
|
+
JSON.parse(response)
|
50
|
+
end
|
51
|
+
rescue JSON::ParserError => e
|
52
|
+
raise ServiceNotAvailable.new
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def rescue_json_parsing(&block)
|
57
|
+
begin
|
58
|
+
yield
|
59
|
+
rescue ::RestClient::Exception => e
|
60
|
+
hash_response(e.http_body)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
data/lib/panda/base.rb
CHANGED
@@ -1,18 +1,22 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
module Panda
|
2
|
-
class Base
|
4
|
+
class Base
|
3
5
|
attr_accessor :attributes, :errors
|
6
|
+
extend Forwardable
|
7
|
+
|
4
8
|
include Panda::Router
|
9
|
+
include Panda::Builders
|
10
|
+
include Panda::Finders
|
11
|
+
|
12
|
+
def_delegators :attributes, :to_json
|
5
13
|
|
6
14
|
def initialize(attributes = {})
|
7
|
-
|
15
|
+
clear_attributes
|
8
16
|
load(attributes)
|
9
17
|
end
|
10
18
|
|
11
19
|
class << self
|
12
|
-
def id(this_id)
|
13
|
-
find(this_id)
|
14
|
-
end
|
15
|
-
|
16
20
|
def sti_name
|
17
21
|
"#{name.split('::').last}"
|
18
22
|
end
|
@@ -26,11 +30,6 @@ module Panda
|
|
26
30
|
id.nil?
|
27
31
|
end
|
28
32
|
|
29
|
-
def delete
|
30
|
-
response = connection.delete(object_url_map(self.class.one_path))
|
31
|
-
!!response['deleted']
|
32
|
-
end
|
33
|
-
|
34
33
|
def id
|
35
34
|
attributes['id']
|
36
35
|
end
|
@@ -44,41 +43,44 @@ module Panda
|
|
44
43
|
self
|
45
44
|
end
|
46
45
|
|
47
|
-
def to_json
|
48
|
-
attributes.to_json
|
49
|
-
end
|
50
|
-
|
51
46
|
private
|
52
47
|
|
48
|
+
def load_and_reset(response)
|
49
|
+
load_response(response)
|
50
|
+
end
|
51
|
+
|
53
52
|
def perform_reload(args={})
|
54
53
|
raise "RecordNotFound" if new?
|
55
54
|
|
56
|
-
url = self.class.
|
55
|
+
url = self.class.create_rest_url(self.class.one_path, :id => id)
|
57
56
|
response = connection.get(url)
|
58
|
-
init_load
|
59
57
|
load_response(response.merge(args))
|
60
58
|
end
|
61
59
|
|
62
|
-
def
|
60
|
+
def clear_attributes
|
63
61
|
@attributes = {}
|
64
62
|
@changed_attributes = {}
|
65
63
|
@errors = []
|
66
64
|
end
|
67
65
|
|
68
66
|
def load(attributes)
|
67
|
+
not_a_response = !(attributes['id'] || attributes[:id])
|
69
68
|
attributes.each do |key, value|
|
70
69
|
@attributes[key.to_s] = value
|
71
|
-
@changed_attributes[key.to_s] = value if
|
70
|
+
@changed_attributes[key.to_s] = value if not_a_response
|
72
71
|
end
|
73
72
|
true
|
74
73
|
end
|
75
74
|
|
76
75
|
def load_response(response)
|
77
76
|
if response['error'] || response['id'].nil?
|
78
|
-
|
77
|
+
@errors << APIError.new(response)
|
78
|
+
@loaded = false
|
79
79
|
else
|
80
|
-
|
80
|
+
clear_attributes
|
81
81
|
load(response)
|
82
|
+
@changed_attributes = {};
|
83
|
+
@loaded = true
|
82
84
|
end
|
83
85
|
end
|
84
86
|
|