panda 0.6.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ module Panda
2
+ class ProfileScope < Scope
3
+ def initialize(parent)
4
+ super(parent, Profile)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,25 @@
1
+ module Panda
2
+ class Proxy
3
+ include Panda::Router::ClassMethods
4
+ include Panda::Finders::FindMany
5
+ include Panda::Finders::FindOne
6
+ include Panda::Builders::CreateBuilder
7
+ include Panda::CloudConnection
8
+
9
+ attr_accessor :parent, :klass
10
+
11
+ def initialize(parent, klass)
12
+ @parent = parent
13
+ @klass = klass
14
+ end
15
+
16
+ def cloud
17
+ @parent.is_a?(Cloud) ? @parent : @parent.cloud
18
+ end
19
+
20
+ def end_class_name
21
+ klass.end_class_name
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,87 @@
1
+ require 'forwardable'
2
+
3
+ module Panda
4
+ class Scope < Proxy
5
+ extend Forwardable
6
+
7
+ def respond_to?(method)
8
+ scoped_methods = [].methods.map{|i| i.to_sym} - non_delegate_methods + [:reload, :non_delegate_methods]
9
+ !(scoped_methods).include?(method.to_sym)
10
+ end
11
+
12
+ def non_delegate_methods
13
+ [:nil?, :send, :object_id, :respond_to?, :class, :find, :find_by, :create, :create!, :all, :cloud, :connection]
14
+ end
15
+
16
+ def initialize(parent, klass)
17
+ super
18
+
19
+ initialize_scope_attributes
20
+ initialize_scopes
21
+ end
22
+
23
+ # Overide the function to set the cloud_id as the same as the scope
24
+ def find_by_path(url, map={})
25
+ object = find_object_by_path(url, map)
26
+
27
+ if object.is_a?(Array)
28
+ object.map{|o| klass.new(o.merge("cloud_id" => cloud.id))}
29
+ elsif object["id"]
30
+ klass.new(object.merge("cloud_id" => cloud.id))
31
+ else
32
+ Error.new(object).raise!
33
+ end
34
+ end
35
+
36
+ def create(attributes)
37
+ scoped_attrs = attributes.merge(@scoped_attributes)
38
+ super(scoped_attrs)
39
+ end
40
+
41
+ def all(attributes={})
42
+ @scoped_attributes.merge!(attributes)
43
+ trigger_request
44
+ end
45
+
46
+ def reload
47
+ @found = trigger_request
48
+ end
49
+
50
+ private
51
+
52
+ def initialize_scope_attributes
53
+ @scoped_attributes={}
54
+ if @parent.is_a?(Panda::Resource)
55
+ @scoped_attributes[parent_relation_name.to_sym] = @parent.id
56
+ end
57
+ end
58
+
59
+ def proxy_found
60
+ @found ||= trigger_request
61
+ end
62
+
63
+ def initialize_scopes
64
+ [].methods.each do |m|
65
+ unless m.to_s =~ /^__/ || non_delegate_methods.include?(m.to_sym)
66
+ self.class.class_eval do
67
+ def_delegators :proxy_found, m.to_sym
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ def trigger_request
74
+ if @parent.is_a?(Resource)
75
+ path = build_hash_many_path(many_path, parent_relation_name)
76
+ else
77
+ path = many_path
78
+ end
79
+
80
+ find_by_path(path, @scoped_attributes)
81
+ end
82
+
83
+ def parent_relation_name
84
+ "#{@parent.class.end_class_name.downcase}_id"
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,28 @@
1
+ module Panda
2
+ class VideoScope < Scope
3
+
4
+ def initialize(parent)
5
+ super(parent, Video)
6
+ end
7
+
8
+ def non_delegate_methods
9
+ super + [:status, :page, :per_page]
10
+ end
11
+
12
+ def page(this_page)
13
+ @scoped_attributes[:page] = this_page
14
+ self
15
+ end
16
+
17
+ def per_page(this_per_page)
18
+ @scoped_attributes[:per_page] = this_per_page
19
+ self
20
+ end
21
+
22
+ def status(this_status)
23
+ @scoped_attributes[:status] = this_status
24
+ self
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,49 @@
1
+ module Panda
2
+ class Cloud < Base
3
+ include Panda::Updatable
4
+ attr_reader :connection
5
+
6
+ def initialize(attributes={})
7
+ super(attributes)
8
+ connection_params = Panda.connection.to_hash.merge!(:cloud_id => id, :format => :hash)
9
+ @connection = Connection.new(connection_params)
10
+ Panda.clouds[id] = self
11
+ end
12
+
13
+ class << self
14
+ include Panda::Finders::FindOne
15
+
16
+ def find(id, options=nil)
17
+ super(id)
18
+ end
19
+
20
+ def connection
21
+ Panda.connection
22
+ end
23
+ end
24
+
25
+ def videos
26
+ VideoScope.new(self)
27
+ end
28
+
29
+ def encodings
30
+ EncodingScope.new(self)
31
+ end
32
+
33
+ def profiles
34
+ ProfileScope.new(self)
35
+ end
36
+
37
+ def method_missing(method_symbol, *arguments)
38
+ lazy_load
39
+ super
40
+ end
41
+
42
+ private
43
+
44
+ def lazy_load
45
+ @found ||= reload
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,30 @@
1
+ module Panda
2
+ class Encoding < Resource
3
+ include ShortStatus
4
+
5
+ belongs_to :video
6
+ has_one :profile
7
+
8
+ def url
9
+ "http://s3.amazonaws.com/#{cloud.s3_videos_bucket}/#{id}#{extname}"
10
+ end
11
+
12
+ def screenshots
13
+ @screenshots ||=
14
+ if status == 'success'
15
+ (1..7).map do |i|
16
+ "http://s3.amazonaws.com/#{cloud.s3_videos_bucket}/#{id}_#{i}.jpg"
17
+ end
18
+ else
19
+ []
20
+ end
21
+ end
22
+
23
+ class << self
24
+ def first
25
+ EncodingScope.new(self).per_page(1).first
26
+ end
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ module Panda
2
+ class Profile < Resource
3
+ include Panda::Updatable
4
+
5
+ has_many :encodings
6
+
7
+ def preset?
8
+ !preset_name
9
+ end
10
+
11
+ # override attributes command and preset_name
12
+ # to ovoid <method undefined> when profile is a preset or not
13
+ def command
14
+ @attributes['command']
15
+ end
16
+
17
+ def preset_name
18
+ @attributes['preset_name']
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,52 @@
1
+ module Panda
2
+ class Resource < Base
3
+ include Panda::Builders
4
+ include Panda::Associations
5
+ include Panda::CloudConnection
6
+
7
+ def initialize(attributes={})
8
+ super(attributes)
9
+ @attributes['cloud_id'] ||= Panda.cloud.id
10
+ end
11
+
12
+ class << self
13
+ include Panda::Finders::FindMany
14
+ include Panda::CloudConnection
15
+
16
+ def cloud
17
+ Panda.cloud
18
+ end
19
+
20
+ # delegate to the scope if the method exists
21
+ def method_missing(method_symbol, *args, &block)
22
+ scope = Panda::const_get("#{end_class_name}Scope").new(self)
23
+ if scope.respond_to?(method_symbol)
24
+ scope.send(method_symbol, *args, &block)
25
+ else
26
+ super
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ def cloud
33
+ Panda.clouds[cloud_id]
34
+ end
35
+
36
+ def create
37
+ raise "Can't create attribute. Already have an id=#{attributes['id']}" if attributes['id']
38
+ response = connection.post(object_url_map(self.class.many_path), attributes)
39
+ load_response(response) ? (@changed_attributes = {}; true) : false
40
+ end
41
+
42
+ def create!
43
+ create || errors.last.raise!
44
+ end
45
+
46
+ def reload
47
+ perform_reload("cloud_id" => cloud_id)
48
+ reset_associations
49
+ self
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,13 @@
1
+ module Panda
2
+ class Video < Resource
3
+ include ShortStatus
4
+ has_many :encodings
5
+
6
+ class << self
7
+ def first
8
+ VideoScope.new(self).per_page(1).first
9
+ end
10
+ end
11
+
12
+ end
13
+ end
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.6.4"
8
+ s.version = "1.0.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-07-01}
12
+ s.date = %q{2010-08-05}
13
13
  s.description = %q{Panda Client}
14
14
  s.email = %q{info@pandastream.com}
15
15
  s.extra_rdoc_files = [
@@ -18,18 +18,43 @@ Gem::Specification.new do |s|
18
18
  ]
19
19
  s.files = [
20
20
  ".gitignore",
21
+ "Gemfile",
21
22
  "LICENSE",
22
23
  "README.md",
23
24
  "Rakefile",
24
25
  "VERSION",
25
26
  "lib/panda.rb",
26
27
  "lib/panda/api_authentication.rb",
28
+ "lib/panda/base.rb",
29
+ "lib/panda/connection.rb",
30
+ "lib/panda/error.rb",
31
+ "lib/panda/modules/associations.rb",
32
+ "lib/panda/modules/builders.rb",
33
+ "lib/panda/modules/cloud_connection.rb",
34
+ "lib/panda/modules/finders.rb",
35
+ "lib/panda/modules/router.rb",
36
+ "lib/panda/modules/short_status.rb",
37
+ "lib/panda/modules/updatable.rb",
27
38
  "lib/panda/panda.rb",
28
- "log/debug.log",
39
+ "lib/panda/proxies/encoding_scope.rb",
40
+ "lib/panda/proxies/profile_scope.rb",
41
+ "lib/panda/proxies/proxy.rb",
42
+ "lib/panda/proxies/scope.rb",
43
+ "lib/panda/proxies/video_scope.rb",
44
+ "lib/panda/resources/cloud.rb",
45
+ "lib/panda/resources/encoding.rb",
46
+ "lib/panda/resources/profile.rb",
47
+ "lib/panda/resources/resource.rb",
48
+ "lib/panda/resources/video.rb",
29
49
  "panda.gemspec",
50
+ "spec/cloud_spec.rb",
51
+ "spec/encoding_spec.rb",
52
+ "spec/heroku_spec.rb",
30
53
  "spec/panda_spec.rb",
54
+ "spec/profile_spec.rb",
31
55
  "spec/spec.opts",
32
- "spec/spec_helper.rb"
56
+ "spec/spec_helper.rb",
57
+ "spec/video_spec.rb"
33
58
  ]
34
59
  s.homepage = %q{http://github.com/newbamboo/panda_gem}
35
60
  s.rdoc_options = ["--charset=UTF-8"]
@@ -37,8 +62,13 @@ Gem::Specification.new do |s|
37
62
  s.rubygems_version = %q{1.3.5}
38
63
  s.summary = %q{Panda Client}
39
64
  s.test_files = [
40
- "spec/panda_spec.rb",
41
- "spec/spec_helper.rb"
65
+ "spec/cloud_spec.rb",
66
+ "spec/encoding_spec.rb",
67
+ "spec/heroku_spec.rb",
68
+ "spec/panda_spec.rb",
69
+ "spec/profile_spec.rb",
70
+ "spec/spec_helper.rb",
71
+ "spec/video_spec.rb"
42
72
  ]
43
73
 
44
74
  if s.respond_to? :specification_version then
@@ -46,21 +76,15 @@ Gem::Specification.new do |s|
46
76
  s.specification_version = 3
47
77
 
48
78
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
49
- s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
50
- s.add_development_dependency(%q<webmock>, [">= 0"])
51
79
  s.add_runtime_dependency(%q<ruby-hmac>, [">= 0.3.2"])
52
80
  s.add_runtime_dependency(%q<rest-client>, [">= 1.4"])
53
81
  s.add_runtime_dependency(%q<json>, [">= 1.2"])
54
82
  else
55
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
56
- s.add_dependency(%q<webmock>, [">= 0"])
57
83
  s.add_dependency(%q<ruby-hmac>, [">= 0.3.2"])
58
84
  s.add_dependency(%q<rest-client>, [">= 1.4"])
59
85
  s.add_dependency(%q<json>, [">= 1.2"])
60
86
  end
61
87
  else
62
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
63
- s.add_dependency(%q<webmock>, [">= 0"])
64
88
  s.add_dependency(%q<ruby-hmac>, [">= 0.3.2"])
65
89
  s.add_dependency(%q<rest-client>, [">= 1.4"])
66
90
  s.add_dependency(%q<json>, [">= 1.2"])
@@ -0,0 +1,80 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Panda::Video do
4
+ describe "Using configure bloc" do
5
+ before(:each) do
6
+ Panda.configure do |c|
7
+ c.access_key = "my_access_key"
8
+ c.secret_key = "my_secret_key"
9
+ c.api_host = "api.example.com"
10
+ c.cloud_id = 'my_cloud_id'
11
+ c.api_port = 85
12
+ end
13
+ end
14
+
15
+ describe "using a cloud" do
16
+ before(:each) do
17
+ cloud_json = "{\"s3_videos_bucket\":\"my_bucket1\",\"id\":\"cloud1\"}"
18
+ stub_http_request(:get, /api.example.com:85\/v2\/clouds\/cloud1.json/).
19
+ to_return(:body => cloud_json)
20
+ @cloud = Panda::Cloud.find "cloud1"
21
+ end
22
+
23
+ it "should find all videos" do
24
+ videos_json = "[{\"source_url\":\"my_source_url\",\"id\":\"123\"}]"
25
+ stub_http_request(:get, /api.example.com:85\/v2\/videos.json/).
26
+ with{|r| r.uri.query =~ /cloud_id=cloud1/}.
27
+ to_return(:body => videos_json)
28
+
29
+ @cloud.videos.first.id.should == "123"
30
+ end
31
+
32
+ it "should find all videos with params" do
33
+ videos_json = "[{\"source_url\":\"my_source_url\",\"id\":\"134\"}]"
34
+ stub_http_request(:get, /api.example.com:85\/v2\/videos.json/).
35
+ with{|r| r.uri.query =~ /status=success/ && r.uri.query =~ /cloud_id=cloud1/}.
36
+ to_return(:body => videos_json)
37
+ videos = @cloud.videos.all(:status => "success")
38
+ videos.first.id.should == "134"
39
+ end
40
+
41
+ it "should find a video by id" do
42
+ video_json = "{\"source_url\":\"my_source_url\",\"id\":\"123\"}"
43
+ stub_http_request(:get, /api.example.com:85\/v2\/videos\/123.json/).
44
+ with{|r| r.uri.query =~ /cloud_id=cloud1/}.
45
+ to_return(:body => video_json)
46
+
47
+ video = @cloud.videos.find "123"
48
+ video.id.should == "123"
49
+ end
50
+
51
+ it "should find all video with params" do
52
+ videos_json = "{\"source_url\":\"my_source_url\",\"id\":\"123\"}"
53
+ stub_http_request(:post, /api.example.com:85\/v2\/videos.json/).
54
+ with{|r| r.body =~ /cloud_id=cloud1/}.
55
+ to_return(:body => videos_json)
56
+ @cloud.videos.create(:source_url => "my_source_url")
57
+ end
58
+ end
59
+
60
+ describe "Using options on find" do
61
+
62
+ it "should find a cloud" do
63
+ cloud_json = "{\"s3_videos_bucket\":\"my_bucket\",\"id\":\"my_cloud_id\"}"
64
+ stub_http_request(:get, /http:\/\/api.example.com:85\/v2\/clouds\/my_cloud_id.json/).
65
+ to_return(:body => cloud_json)
66
+
67
+ @cloud = Panda::Cloud.find "my_cloud_id", {
68
+ "access_key" => "my_access_key",
69
+ "secret_key" => "my_secret_key",
70
+ "api_host" => "api.example.com",
71
+ "api_port" => 85,
72
+ "format" => "json"
73
+ }
74
+
75
+ @cloud.s3_videos_bucket.should == "my_bucket"
76
+ end
77
+ end
78
+
79
+ end
80
+ end