videojuicer-vj-sdk 0.1.5 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/Rakefile +3 -3
  2. data/VERSION.yml +1 -1
  3. data/lib/core_ext/hash.rb +13 -1
  4. data/lib/core_ext/object.rb +15 -0
  5. data/lib/core_ext/string.rb +11 -0
  6. data/lib/sdk_connection_harness.rb +25 -11
  7. data/lib/videojuicer.rb +13 -9
  8. data/lib/videojuicer/asset/audio.rb +5 -4
  9. data/lib/videojuicer/asset/base.rb +30 -15
  10. data/lib/videojuicer/asset/flash.rb +8 -0
  11. data/lib/videojuicer/asset/image.rb +2 -2
  12. data/lib/videojuicer/asset/video.rb +12 -9
  13. data/lib/videojuicer/campaign.rb +10 -1
  14. data/lib/videojuicer/campaign_policy.rb +116 -0
  15. data/lib/videojuicer/criterion/base.rb +56 -0
  16. data/lib/videojuicer/criterion/date_range.rb +7 -17
  17. data/lib/videojuicer/criterion/geolocation.rb +11 -20
  18. data/lib/videojuicer/criterion/request.rb +8 -17
  19. data/lib/videojuicer/criterion/time.rb +8 -18
  20. data/lib/videojuicer/criterion/week_day.rb +13 -17
  21. data/lib/videojuicer/oauth/request_proxy.rb +19 -13
  22. data/lib/videojuicer/presentation.rb +6 -0
  23. data/lib/videojuicer/promo/base.rb +72 -0
  24. data/lib/videojuicer/resource/base.rb +17 -15
  25. data/lib/videojuicer/resource/embeddable.rb +30 -0
  26. data/lib/videojuicer/resource/inferrable.rb +67 -7
  27. data/lib/videojuicer/resource/property_registry.rb +19 -0
  28. data/lib/videojuicer/resource/relationships/belongs_to.rb +2 -1
  29. data/lib/videojuicer/resource/types.rb +28 -0
  30. data/spec/assets/audio_spec.rb +24 -0
  31. data/spec/assets/flash_spec.rb +24 -0
  32. data/spec/assets/image_spec.rb +24 -0
  33. data/spec/assets/text_spec.rb +24 -0
  34. data/spec/assets/video_spec.rb +24 -0
  35. data/spec/campaign_policy_spec.rb +41 -0
  36. data/spec/campaign_spec.rb +0 -12
  37. data/spec/criterion/date_range_spec.rb +24 -0
  38. data/spec/criterion/geolocation_spec.rb +23 -0
  39. data/spec/criterion/request_spec.rb +23 -0
  40. data/spec/criterion/time_spec.rb +23 -0
  41. data/spec/criterion/week_day_spec.rb +23 -0
  42. data/spec/files/flash.swf +0 -0
  43. data/spec/helpers/be_equal_to.rb +26 -0
  44. data/spec/helpers/spec_fixtures.rb +214 -0
  45. data/spec/helpers/spec_helper.rb +27 -25
  46. data/spec/presentation_spec.rb +2 -15
  47. data/spec/promos/audio_spec.rb +23 -0
  48. data/spec/promos/image_spec.rb +24 -0
  49. data/spec/promos/text_spec.rb +23 -0
  50. data/spec/promos/video_spec.rb +23 -0
  51. data/spec/request_proxy_spec.rb +8 -12
  52. data/spec/session_spec.rb +3 -1
  53. data/spec/shared/dependent_spec.rb +40 -0
  54. data/spec/shared/embeddable_spec.rb +34 -0
  55. data/spec/shared/model_spec.rb +74 -0
  56. data/spec/shared/resource_spec.rb +12 -41
  57. data/spec/spec.opts +1 -1
  58. data/spec/user_spec.rb +5 -27
  59. data/tasks/vj-core.rb +3 -2
  60. data/vj-sdk.gemspec +56 -24
  61. metadata +53 -23
  62. data/lib/videojuicer/criterion/affiliate.rb +0 -21
  63. data/lib/videojuicer/criterion/embed.rb +0 -12
  64. data/spec/audio_spec.rb +0 -45
  65. data/spec/criteria/date_range_spec.rb +0 -37
  66. data/spec/criteria/geolocation_spec.rb +0 -38
  67. data/spec/criteria/request_spec.rb +0 -36
  68. data/spec/criteria/time_spec.rb +0 -37
  69. data/spec/criteria/week_day_spec.rb +0 -39
  70. data/spec/image_spec.rb +0 -44
  71. data/spec/text_spec.rb +0 -42
  72. data/spec/video_spec.rb +0 -50
data/Rakefile CHANGED
@@ -6,10 +6,10 @@ begin
6
6
  require 'jeweler'
7
7
  Jeweler::Tasks.new do |gem|
8
8
  gem.name = "vj-sdk"
9
- gem.summary = %Q{TODO}
9
+ gem.summary = "Videojuicer core-sdk"
10
10
  gem.email = "dan@videojuicer.com"
11
11
  gem.homepage = "http://github.com/danski/vj-sdk"
12
- gem.authors = ["danski", "thejohnny", "knowtheory", "sixones"]
12
+ gem.authors = ["danski", "thejohnny", "knowtheory", "sixones", "btab"]
13
13
 
14
14
  # Declare dependencies
15
15
  gem.add_dependency "json", ">= 1.0"
@@ -29,7 +29,7 @@ namespace :spec do
29
29
  task :sdk do
30
30
  require 'tasks/vj-core'
31
31
  Rake::Task["videojuicer:core:setup"].invoke
32
- Rake::Task["spec"].invoke
32
+ Rake::Task["spec"].execute
33
33
  Rake::Task["videojuicer:core:cleanup"].invoke
34
34
  end
35
35
  end
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
3
  :minor: 1
4
- :patch: 5
4
+ :patch: 12
@@ -11,7 +11,19 @@ class Hash
11
11
  memo
12
12
  end
13
13
  end
14
-
14
+
15
+ # Returns a new hash just like this one, but with all the symbol keys expressed as strings.
16
+ # Also applies to hashes within self.
17
+ # Based on an implementation within Rails 2.x, thanks Rails!
18
+ def deep_stringify
19
+ target = dup
20
+ target.inject({}) do |memo, (key, value)|
21
+ value = value.deep_stringify if value.is_a?(Hash)
22
+ memo[(key.to_s rescue key) || key] = value
23
+ memo
24
+ end
25
+ end
26
+
15
27
  # Merges self with another hash, recursively.
16
28
  #
17
29
  # This code was lovingly stolen from some random gem:
@@ -0,0 +1,15 @@
1
+ class Object
2
+
3
+ # Cribbed from DataMapper's Extlib library.
4
+ def full_const_get(name)
5
+ list = name.split("::")
6
+ list.shift if list.first.blank?
7
+ obj = self
8
+ list.each do |x|
9
+ # This is required because const_get tries to look for constants in the
10
+ # ancestor chain, but we only want constants that are HERE
11
+ obj = obj.const_defined?(x) ? obj.const_get(x) : obj.const_missing(x)
12
+ end
13
+ obj
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ class String
2
+ def blank?
3
+ strip.empty?
4
+ end
5
+
6
+ def snake_case
7
+ return self.downcase if self =~ /^[A-Z]+$/
8
+ self.gsub(/([A-Z]+)(?=[A-Z][a-z]?)|\B[A-Z]/, '_\&') =~ /_*(.*)/
9
+ return $+.downcase
10
+ end
11
+ end
@@ -1,4 +1,8 @@
1
- require 'mash'
1
+ begin
2
+ require 'extlib/mash'
3
+ rescue LoadError
4
+ require 'mash'
5
+ end
2
6
  require 'yaml'
3
7
  class SDKConnectionHarness
4
8
  class << self
@@ -16,7 +20,7 @@ class SDKConnectionHarness
16
20
  Thread.new do
17
21
  cur_dir = Dir.pwd
18
22
  Dir.chdir(core_directory) do
19
- `merb -d -p #{port} -e test --log .log/sdk-development.log`
23
+ `./bin/merb -d #{app_server} -p #{port} -e test --log ./log/sdk-development.log`
20
24
  end
21
25
  Dir.chdir(cur_dir)
22
26
  end
@@ -45,7 +49,7 @@ class SDKConnectionHarness
45
49
 
46
50
  def load_fixtures
47
51
  Dir.chdir(core_directory) do
48
- out = `rake videojuicer:sdk:setup MERB_ENV=test`
52
+ out = `./bin/rake videojuicer:sdk:setup MERB_ENV=test`
49
53
  out = out.match(/!!!([^!]+)!!!/m)
50
54
  self.fixtures = out[1]
51
55
  end
@@ -58,18 +62,28 @@ class SDKConnectionHarness
58
62
  f.close
59
63
  end
60
64
 
65
+ def app_server
66
+ begin
67
+ require 'thin'
68
+ adapter = 'thin'
69
+ rescue LoadError
70
+ adapter = 'mongrel'
71
+ end
72
+ return "--adapter #{adapter}"
73
+ end
74
+
61
75
  def port
62
- 5555
76
+ 6666
63
77
  end
64
78
 
65
79
  def connect(overrides={})
66
80
  fixtures = Mash.new(YAML.load(load_fixtures)).merge(overrides)
67
- configure_test_settings(overrides)
68
- Videojuicer.enter_scope :seed_name => fixtures.seed.name,
69
- :consumer_key=>fixtures["write-master"].consumer.consumer_key,
70
- :consumer_secret=>fixtures["write-master"].consumer.consumer_secret,
71
- :token=>fixtures["write-master"].authorized_token.oauth_token,
72
- :token_secret=>fixtures["write-master"].authorized_token.oauth_token_secret
81
+ configure_test_settings(fixtures)
82
+ Videojuicer.enter_scope :seed_name => fixtures[:seed][:name],
83
+ :consumer_key=>fixtures["write-master"][:consumer][:consumer_key],
84
+ :consumer_secret=>fixtures["write-master"][:consumer][:consumer_secret],
85
+ :token=>fixtures["write-master"][:authorized_token][:oauth_token],
86
+ :token_secret=>fixtures["write-master"][:authorized_token][:oauth_token_secret]
73
87
  end
74
88
 
75
89
  def configure_test_settings(overrides={})
@@ -79,7 +93,7 @@ class SDKConnectionHarness
79
93
  :api_version => 1,
80
94
  :protocol => "http",
81
95
  :host => "localhost",
82
- :port => 5555
96
+ :port => port
83
97
  }.merge(overrides))
84
98
  end
85
99
 
@@ -9,6 +9,9 @@ require 'net/http'
9
9
 
10
10
  # Core ext
11
11
  require 'core_ext/hash'
12
+ require 'core_ext/string'
13
+ require 'core_ext/object'
14
+ require 'core_ext/cgi'
12
15
  # Core mixins
13
16
  require 'videojuicer/shared/exceptions'
14
17
  require 'videojuicer/shared/configurable'
@@ -16,6 +19,8 @@ require 'videojuicer/shared/configurable'
16
19
  require 'videojuicer/oauth/request_proxy'
17
20
  require 'videojuicer/oauth/proxy_factory'
18
21
  # Resource handling
22
+ require 'videojuicer/resource/embeddable'
23
+ require 'videojuicer/resource/types'
19
24
  require 'videojuicer/resource/relationships/belongs_to'
20
25
  require 'videojuicer/resource/errors'
21
26
  require 'videojuicer/resource/collection'
@@ -26,19 +31,20 @@ require 'videojuicer/session'
26
31
  # Frontend models
27
32
  require 'videojuicer/user'
28
33
  require 'videojuicer/campaign'
34
+ require 'videojuicer/campaign_policy'
29
35
  require 'videojuicer/presentation'
30
36
  require 'videojuicer/asset/audio'
31
- require 'videojuicer/asset/video'
32
- require 'videojuicer/asset/text'
37
+ require 'videojuicer/asset/flash'
33
38
  require 'videojuicer/asset/image'
34
-
35
- require 'videojuicer/criterion/affiliate'
39
+ require 'videojuicer/asset/text'
40
+ require 'videojuicer/asset/video'
41
+ require 'videojuicer/promo/base'
36
42
  require 'videojuicer/criterion/date_range'
37
- require 'videojuicer/criterion/embed'
38
43
  require 'videojuicer/criterion/geolocation'
39
44
  require 'videojuicer/criterion/request'
40
45
  require 'videojuicer/criterion/time'
41
46
  require 'videojuicer/criterion/week_day'
47
+ require 'videojuicer/promo/base'
42
48
 
43
49
  module Videojuicer
44
50
 
@@ -99,7 +105,5 @@ module Videojuicer
99
105
  def default_options
100
106
  @default_options
101
107
  end
102
- end
103
-
104
-
105
- end
108
+ end # class << self
109
+ end # module Videojuicer
@@ -3,10 +3,11 @@ require File.join(File.dirname(__FILE__), "base")
3
3
  module Videojuicer
4
4
  module Asset
5
5
  class Audio < Base
6
- property :bit_rate, Integer # bits per second
7
- property :format, String
8
- property :sample_rate, Integer # hertz
9
- property :stereo, String
6
+ property :bit_rate, Integer, :writer => :private # bits per second
7
+ property :channels, Integer, :writer => :private
8
+ property :duration, Integer, :writer => :private # milliseconds
9
+ property :format, String, :writer => :private
10
+ property :sample_rate, Integer, :writer => :private # hertz
10
11
  end
11
12
  end
12
13
  end
@@ -7,23 +7,34 @@ module Videojuicer
7
7
  base.send(:extend, Videojuicer::Asset::Base::ClassMethods)
8
8
  base.send(:include, Videojuicer::Asset::Base::InstanceMethods)
9
9
 
10
- base.property :user_id, Integer
10
+ # - heritage
11
+ base.property :original_asset_id, Integer, :writer => :private
12
+ base.property :original_asset_type, String, :writer => :private
13
+ base.property :preset_id, Integer, :writer => :private
14
+ base.property :user_id, Integer, :writer => :private
15
+
16
+ # - transformation
17
+ base.property :source_space_window, String, :writer => :private
18
+ base.property :source_time_window, String, :writer => :private
19
+
11
20
  # - generic file handling
12
- base.property :file, File
13
- base.property :file_name, String
14
- base.property :file_size, Integer, :writer=>:private
21
+ base.property :file, File
22
+ base.property :file_name, String
23
+ base.property :file_size, Integer, :writer => :private # bytes
24
+
15
25
  # - common metadata
16
- base.property :duration, Integer # milliseconds
17
- base.property :licensed_at, Date
18
- base.property :licensed_by, String
19
- base.property :licensed_under, String
20
- base.property :published_at, Date
21
- # - access control / workflow
22
- base.property :state, String, :writer => :private
23
- base.property :url, String, :writer => :private
26
+ base.property :licensed_at, Date
27
+ base.property :licensed_by, String
28
+ base.property :licensed_under, String
29
+ base.property :published_at, Date
24
30
 
25
- base.property :created_at, DateTime
26
- base.property :updated_at, DateTime
31
+ # - access control / workflow
32
+ base.property :url, String, :writer => :private
33
+ base.property :state, String, :writer => :private
34
+ base.property :state_changed_at, DateTime, :writer => :private
35
+ base.property :state_changed_url, String
36
+ base.property :created_at, DateTime
37
+ base.property :updated_at, DateTime
27
38
  end
28
39
 
29
40
  module ClassMethods
@@ -31,12 +42,16 @@ module Videojuicer
31
42
  "asset"
32
43
  end
33
44
 
34
- def base_path
45
+ def base_path(options={})
35
46
  "/assets/#{self.to_s.downcase.split("::").last}"
36
47
  end
37
48
  end
38
49
 
39
50
  module InstanceMethods
51
+ def file
52
+ raise "use the value of #{self.class}#url to download a copy of the asset"
53
+ end
54
+
40
55
  def returnable_attributes
41
56
  attrs = super
42
57
  attrs.delete(:file) unless new_record?
@@ -0,0 +1,8 @@
1
+ require File.join(File.dirname(__FILE__), "base")
2
+
3
+ module Videojuicer
4
+ module Asset
5
+ class Flash < Base
6
+ end
7
+ end
8
+ end
@@ -3,8 +3,8 @@ require File.join(File.dirname(__FILE__), "base")
3
3
  module Videojuicer
4
4
  module Asset
5
5
  class Image < Base
6
- property :width, Integer # pixels
7
- property :height, Integer # pixels
6
+ property :width, Integer, :writer => :private # pixels
7
+ property :height, Integer, :writer => :private # pixels
8
8
  end
9
9
  end
10
10
  end
@@ -3,17 +3,20 @@ require File.join(File.dirname(__FILE__), "base")
3
3
  module Videojuicer
4
4
  module Asset
5
5
  class Video < Base
6
- property :audio_bit_rate, Integer # bits per second
7
- property :audio_format, String
8
- property :audio_sample_rate, Integer # hertz
9
- property :audio_stereo, String
6
+ property :bit_rate, Integer, :writer => :private # bits per second
7
+ property :duration, Integer, :writer => :private # milliseconds
10
8
 
11
- property :video_bit_rate, Integer # bits per second
12
- property :video_format, String
13
- property :video_frame_rate, Float # frames per second
9
+ property :audio_bit_rate, Integer, :writer => :private # bits per second
10
+ property :audio_channels, Integer, :writer => :private
11
+ property :audio_format, String, :writer => :private
12
+ property :audio_sample_rate, Integer, :writer => :private # hertz
14
13
 
15
- property :width, Integer # pixels
16
- property :height, Integer # pixels
14
+ property :video_bit_rate, Integer, :writer => :private # bits per second
15
+ property :video_format, String, :writer => :private
16
+ property :video_frame_rate, Float, :writer => :private # frames per second
17
+
18
+ property :width, Integer, :writer => :private # pixels
19
+ property :height, Integer, :writer => :private # pixels
17
20
  end
18
21
  end
19
22
  end
@@ -3,6 +3,15 @@ module Videojuicer
3
3
  include Videojuicer::Resource
4
4
  include Videojuicer::Exceptions
5
5
 
6
- property :name, String
6
+ property :name, String
7
+ property :user_id, Integer
8
+ belongs_to :user, :class=>Videojuicer::User
9
+
10
+ attr_accessor :campaign_policies
11
+ def campaign_policies=(arg)
12
+ # Loop over and make objects or something
13
+ @campaign_policies=(arg)
14
+ end
15
+
7
16
  end
8
17
  end
@@ -0,0 +1,116 @@
1
+ module Videojuicer
2
+ class Campaign
3
+ class CampaignPolicy
4
+ include Videojuicer::Resource
5
+
6
+ # Resource should note that this is a class within a class
7
+ # Should treat parent class as parent resource
8
+
9
+ property :presentation_id, Integer
10
+ property :campaign_id, Integer
11
+ property :created_at, DateTime
12
+ property :updated_at, DateTime
13
+
14
+ belongs_to :campaign
15
+
16
+ attr_accessor :criteria
17
+ def criteria=(object_hash)
18
+ # TODO instantiate criteria in a useful object of some sort
19
+
20
+ # Fail unless arg is an array
21
+ # Loop over array do |mem|
22
+ # if mem is a hash
23
+ # instantiate as a criterion
24
+
25
+
26
+ # if criterion object already on this policy
27
+ # leave be
28
+ # else
29
+ # add_criteria(mem)
30
+ # end
31
+ # end
32
+
33
+ # what you want to be able to do is:
34
+ # policy.criteria.include?(some_criterion)
35
+ @criteria = {}
36
+ object_hash.map do |type_sym, criteria|
37
+ @criteria[type_sym.to_sym] =
38
+ criteria.map do |criterion|
39
+ Videojuicer::Criterion.model_map[type_sym.to_sym].new(criterion) #rescue raise("No criteria class found for #{type_sym} in #{Videojuicer::Criterion.model_map.inspect}")
40
+ end
41
+ end
42
+ end
43
+
44
+ def criteria
45
+ @criteria.values.flatten
46
+ end
47
+
48
+ %w(date_criteria geolocation_criteria request_criteria time_criteria week_day_criteria).each do |key|
49
+ class_eval <<-DEF
50
+ def #{key}
51
+ @criteria[:#{key}]
52
+ end
53
+ DEF
54
+ end
55
+
56
+
57
+ def add_criteria(*criteria)
58
+ responses = criteria.map do |criterion|
59
+ proxy_for(config).post("#{path_for_dependents}#{criterion.class.base_path}", {:criterion => criterion.attributes})
60
+ end
61
+ self.reload
62
+ responses
63
+ end
64
+
65
+ def remove_criteria(*criteria)
66
+ responses = criteria.map do |criterion|
67
+ proxy_for(config).delete("#{path_for_dependents}#{criterion.class.base_path}", {:criterion => criterion.attributes})
68
+ end
69
+ self.reload
70
+ responses
71
+ end
72
+
73
+ def promos=(object_hash={})
74
+ @promos = {}
75
+ object_hash.map do |type_sym, promos|
76
+ @promos[type_sym.to_sym] =
77
+ promos.map do |promo|
78
+ Videojuicer::Promo.model_map[type_sym.to_sym].new(promo)
79
+ end
80
+ end
81
+ end
82
+
83
+ def promos
84
+ @promos.values.flatten
85
+ end
86
+
87
+ %w(audio images texts videos).each do |key|
88
+ class_eval <<-DEF
89
+ def #{key}
90
+ @promos[:#{key}]
91
+ end
92
+ DEF
93
+ end
94
+
95
+ def add_promo(*promos)
96
+ responses = promos.map do |promo|
97
+ proxy_for(config).post("#{path_for_dependents}#{promo.class.base_path}", {:promo => promo.attributes})
98
+ end
99
+ self.reload
100
+ responses
101
+ end
102
+
103
+ def remove_promo(*promos)
104
+ responses = promos.map do |promo|
105
+ proxy_for(config).delete("#{path_for_dependents}#{promo.class.base_path}", {:promo => promo.attributes})
106
+ end
107
+ self.reload
108
+ responses
109
+ end
110
+
111
+ def path_for_dependents
112
+ self.class.compile_route(self.class.nesting_route,{:campaign_policy_id => self.id, :campaign_id => self.campaign_id})
113
+ end
114
+ end
115
+ end
116
+ end