panda 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
File without changes
@@ -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
@@ -1,14 +1,2 @@
1
- source :rubygems
2
-
3
- group :development, :test do
4
-
5
- gem "ruby-hmac",">= 0.3.2"
6
- gem "rest-client"
7
- gem "json"
8
-
9
- gem "jeweler"
10
- gem "rake"
11
- gem "rspec", "1.3.1"
12
- gem "webmock", "1.6.1"
13
-
14
- end
1
+ source "http://rubygems.org"
2
+ gemspec
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 |config|
19
- config.access_key = "panda_access_key"
20
- config.secret_key = "panda_secret_key"
21
- config.cloud_id = "panda_cloud_id"
22
- # config.api_host = "api.eu.pandastream.com" ## for EU accounts
23
- # config.api_port = 80 ## to use http (default 443)
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
- ### Creating an instance using Heroku
28
+ ### Inside a Rails app with a main account or using Heroku Addon
29
29
 
30
- Panda.configure(ENV['PANDASTREAM_URL'])
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
- ### Inside a Rails app with a main account or using Heroku
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
- 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).
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
- To do this, a method `signed_params()` is supported:
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 'rubygems'
2
- require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "panda"
8
- gem.summary = %Q{Panda Client}
9
- gem.description = %Q{Panda Client}
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
@@ -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/short_status'
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/error'
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,4 @@
1
+ module Panda
2
+ module Adapter
3
+ end
4
+ end
@@ -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
+
@@ -24,6 +24,8 @@ module Panda
24
24
  Base64.encode64(hmac.digest).chomp
25
25
  end
26
26
 
27
+ private
28
+
27
29
  # param keys should be strings, not symbols please. return a string joined
28
30
  # by & in canonical order.
29
31
  def self.canonical_querystring(h)
@@ -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
- init_load
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.object_url(self.class.one_path, :id => id)
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 init_load
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 !(attributes['id'] || attributes[:id])
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
- !(@errors << Error.new(response))
77
+ @errors << APIError.new(response)
78
+ @loaded = false
79
79
  else
80
- @errors=[]
80
+ clear_attributes
81
81
  load(response)
82
+ @changed_attributes = {};
83
+ @loaded = true
82
84
  end
83
85
  end
84
86