panda 1.3.0 → 1.4.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/.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
|
|