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
@@ -0,0 +1,30 @@
1
+ =begin rdoc
2
+
3
+ A module that provides OEmbed functionality to any Videojuicer::Resource model.
4
+
5
+ =end
6
+
7
+ module Videojuicer
8
+ module Resource
9
+ module Embeddable
10
+
11
+ OEMBED_ENDPOINT = "/oembed".freeze
12
+
13
+ def oembed_payload(maxwidth, maxheight)
14
+ proxy = proxy_for(config)
15
+ result = proxy.get(OEMBED_ENDPOINT, :format=>"json", :url=>"#{proxy.host_stub}#{resource_path}?seed_name=#{seed_name}", :maxwidth=>maxwidth, :maxheight=>maxheight)
16
+ JSON.parse(result.body)
17
+ end
18
+
19
+ def embed_size(maxwidth, maxheight)
20
+ p = oembed_payload(maxwidth, maxheight)
21
+ return p["width"], p["height"]
22
+ end
23
+
24
+ def embed_code(maxwidth, maxheight)
25
+ oembed_payload(maxwidth, maxheight)["html"]
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -29,10 +29,56 @@ module Videojuicer
29
29
 
30
30
  def self.included(base)
31
31
  base.extend(SingletonMethods)
32
+ base.send :include, InstanceMethods
33
+ end
34
+
35
+ module InstanceMethods
36
+ # Returns the appropriate resource path for this object.
37
+ # If the object is a new record, then the root object type path
38
+ # will be given. If the object is not new (has an ID) then the
39
+ # specific ID will be used.
40
+ def resource_path(action=nil, route_options={})
41
+ route_options = {:id=>id}.merge(route_options) unless new_record?
42
+ r = self.class.resource_route(action, route_options)
43
+ self.class.compile_route(r, attributes)
44
+ end
32
45
  end
33
46
 
34
47
  module SingletonMethods
35
48
 
49
+ def compile_route(mask, properties={})
50
+ properties = properties.deep_stringify
51
+ result = []
52
+ mask.split("/").each do |member|
53
+ if member[0..0] == ":"
54
+ result << (properties[member.delete(":")])
55
+ else
56
+ result << member
57
+ end
58
+ end
59
+ "#{result.join("/")}"
60
+ end
61
+
62
+ # Nested resources are inferred from the class hierarchy:
63
+ # Something.parent_class #=> nil
64
+ # Something::Else.parent_class #=> Something
65
+ # Monkeys::Are::Delicious
66
+ def containing_class
67
+ c = self.to_s.split("::"); c.pop
68
+ (c.any?)? Object.full_const_get(c.join("::")) : nil
69
+ end
70
+
71
+ # The route fragment under which nested resources should be mapped.
72
+ def nesting_route
73
+ r = ["/#{plural_name}/#{nesting_route_key}"]
74
+ r = ([(self.containing_class.nesting_route rescue nil)] + r).compact.join("")
75
+ end
76
+
77
+ # The key used by other models when referring to this one in resource routes. User.nesting_route_key == ":user_id"
78
+ def nesting_route_key
79
+ ":#{resource_name}_id"
80
+ end
81
+
36
82
  # Returns the lowercased, underscored version of the including class name.
37
83
  # e.g. Videojuicer::ExampleModel.singular_name => "example_model"
38
84
  def singular_name
@@ -40,13 +86,17 @@ module Videojuicer
40
86
  gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
41
87
  gsub(/([a-z\d])([A-Z])/,'\1_\2').
42
88
  tr("-", "_").
43
- downcase
89
+ downcase.snake_case
44
90
  end
45
91
 
46
92
  # Returns the plural version of the underscored singular name. This method,
47
93
  # when compared directly and fairly to something like ActiveSupport's inflection
48
94
  # module, is an idiot. You would be best to treat it as one.
49
95
  def plural_name
96
+ if singular_name.match(/y$/)
97
+ return singular_name.gsub(/y$/, "ies")
98
+ end
99
+ # Fall back to the simplest rules
50
100
  (singular_name.match(/s$/))? "#{singular_name}es" : "#{singular_name}s"
51
101
  end
52
102
 
@@ -63,16 +113,26 @@ module Videojuicer
63
113
  end
64
114
 
65
115
  # The path to this class's resource given the desired action route.
66
- def resource_path(action=nil)
67
- action_stem = (action)? "/#{action}" : ""
68
- "#{base_path}#{action_stem}"
116
+ # Returned as a mask with replaceable keys e.g. /fixed/fixed/:replaceme/fixed
117
+ def resource_route(action=nil, route_options={})
118
+ id = route_options.delete(:id)
119
+ action_stem = (id)? "/#{id}" : ""
120
+ action_stem += (action)? "/#{action}" : ""
121
+ action_stem += ".json" unless action_stem.empty?
122
+ "#{base_path(route_options)}#{action_stem}"
69
123
  end
70
124
 
71
- # The root path for requests to the API. By default this is inferred from the plural name
125
+ # The root route for requests to the API. By default this is inferred from the plural name
72
126
  # e.g. Videojuicer::Presentation uses /presentations as the resource_path.
73
- def base_path
74
- "/#{plural_name}"
127
+ def base_path(options={})
128
+ options = {
129
+ :nested=>true
130
+ }.merge(options)
131
+ r = "/#{plural_name}"
132
+ r = "#{self.containing_class.nesting_route rescue nil}#{r}" if options[:nested]
133
+ return r
75
134
  end
135
+
76
136
  end
77
137
 
78
138
 
@@ -74,9 +74,28 @@ module Videojuicer
74
74
  return value unless value
75
75
  klass = self.class.attributes[key][:class]
76
76
  if value.is_a?(String) and value.any?
77
+ # In-built types
78
+ if klass.kind_of?(Videojuicer::Resource::Types::Base)
79
+ return klass.new(value).dump
80
+ end
81
+
82
+ # Dates
77
83
  if klass.respond_to?(:parse)
78
84
  return klass.parse(value) rescue raise "Invalid date: #{value.inspect}"
79
85
  end
86
+ elsif value.is_a? Hash and value.any?
87
+ if klass == DateTime
88
+ if value.is_a?(Hash)
89
+ year = value[:year]
90
+ month = value[:month]
91
+ day = value[:day]
92
+ hour = value[:hour] or "00"
93
+ minute = value[:minute] or "00"
94
+ value = klass.parse("#{year}-#{month}-#{day}T#{hour}:#{minute}:00+00:00")
95
+ else
96
+ raise ArgumentError, "Please supply a DateTime, Hash keyed w/ [:day, :month, :year, :hour, :minute] or a String that can be coerced into a date"
97
+ end
98
+ end
80
99
  end
81
100
  return value
82
101
  end
@@ -17,9 +17,10 @@ module Videojuicer
17
17
 
18
18
  define_method name do
19
19
  id = self.send(options[:foreign_key])
20
+ klass = (options[:class].is_a?(String))? Videojuicer.const_get(options[:class]) : options[:class]
20
21
  return nil unless id
21
22
  begin
22
- return options[:class].get(id)
23
+ return klass.get(id)
23
24
  rescue Videojuicer::Exceptions::NoResource
24
25
  return nil
25
26
  end
@@ -0,0 +1,28 @@
1
+ module Videojuicer
2
+ module Resource
3
+ module Types
4
+
5
+ class Base
6
+ def self.load(value)
7
+ return self.new(value)
8
+ end
9
+
10
+ def initialize(value)
11
+ @raw = value
12
+ end
13
+
14
+ # Returns the source value
15
+ attr_reader :raw
16
+ end
17
+
18
+ class Boolean < Base
19
+ # Boolean.new("1").dump #=> true
20
+ # Returns the coerced value
21
+ def dump
22
+ [1, "1", "true", "yes"].include?(raw)
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), "..", "helpers", "spec_helper")
2
+
3
+ describe Videojuicer::Asset::Audio do
4
+
5
+ before(:all) do
6
+ @klass = Videojuicer::Asset::Audio
7
+ configure_test_settings
8
+ end
9
+
10
+ describe "instantiation" do
11
+ it_should_behave_like "a configurable"
12
+ end
13
+
14
+ describe "general interface:" do
15
+ before(:all) do
16
+ @singular_name = "asset"
17
+ @plural_name = "assets/audio"
18
+ end
19
+
20
+ it_should_behave_like "a RESTFUL resource model"
21
+ end
22
+
23
+
24
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), "..", "helpers", "spec_helper")
2
+
3
+ describe Videojuicer::Asset::Flash do
4
+
5
+ before(:all) do
6
+ @klass = Videojuicer::Asset::Flash
7
+ configure_test_settings
8
+ end
9
+
10
+ describe "instantiation" do
11
+ it_should_behave_like "a configurable"
12
+ end
13
+
14
+ describe "general interface:" do
15
+ before(:all) do
16
+ @singular_name = "asset"
17
+ @plural_name = "assets/flash"
18
+ end
19
+
20
+ it_should_behave_like "a RESTFUL resource model"
21
+ end
22
+
23
+
24
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), "..", "helpers", "spec_helper")
2
+
3
+ describe Videojuicer::Asset::Image do
4
+
5
+ before(:all) do
6
+ @klass = Videojuicer::Asset::Image
7
+ configure_test_settings
8
+ end
9
+
10
+ describe "instantiation" do
11
+ it_should_behave_like "a configurable"
12
+ end
13
+
14
+ describe "general interface:" do
15
+ before(:all) do
16
+ @singular_name = "asset"
17
+ @plural_name = "assets/image"
18
+ end
19
+
20
+ it_should_behave_like "a RESTFUL resource model"
21
+ end
22
+
23
+
24
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), "..", "helpers", "spec_helper")
2
+
3
+ describe Videojuicer::Asset::Text do
4
+
5
+ before(:all) do
6
+ @klass = Videojuicer::Asset::Text
7
+ configure_test_settings
8
+ end
9
+
10
+ describe "instantiation" do
11
+ it_should_behave_like "a configurable"
12
+ end
13
+
14
+ describe "general interface:" do
15
+ before(:all) do
16
+ @singular_name = "asset"
17
+ @plural_name = "assets/text"
18
+ end
19
+
20
+ it_should_behave_like "a RESTFUL resource model"
21
+ end
22
+
23
+
24
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), "..", "helpers", "spec_helper")
2
+
3
+ describe Videojuicer::Asset::Video do
4
+
5
+ before(:all) do
6
+ @klass = Videojuicer::Asset::Video
7
+ configure_test_settings
8
+ end
9
+
10
+ describe "instantiation" do
11
+ it_should_behave_like "a configurable"
12
+ end
13
+
14
+ describe "general interface:" do
15
+ before(:all) do
16
+ @singular_name = "asset"
17
+ @plural_name = "assets/video"
18
+ end
19
+
20
+ it_should_behave_like "a RESTFUL resource model"
21
+ end
22
+
23
+
24
+ end
@@ -0,0 +1,41 @@
1
+ require File.join(File.dirname(__FILE__), "helpers", "spec_helper")
2
+
3
+ describe Videojuicer::Campaign::CampaignPolicy do
4
+
5
+ before(:all) do
6
+ @klass = Videojuicer::Campaign::CampaignPolicy
7
+ configure_test_settings
8
+ end
9
+
10
+ describe "instantiation" do
11
+ it_should_behave_like "a configurable"
12
+ end
13
+
14
+ describe "general interface:" do
15
+ before(:all) do
16
+ @singular_name = "campaign_policy"
17
+ @plural_name = "campaign_policies"
18
+ @fixed_attributes = [:campaign_id]
19
+ end
20
+
21
+ it_should_behave_like "a RESTFUL resource model"
22
+ end
23
+
24
+ describe "adding policies" do
25
+
26
+ end
27
+
28
+ describe "removing policies" do
29
+
30
+ end
31
+
32
+ describe "adding promos" do
33
+
34
+ end
35
+
36
+ describe "removing promos" do
37
+
38
+ end
39
+
40
+
41
+ end
@@ -5,15 +5,6 @@ describe Videojuicer::Campaign do
5
5
  before(:all) do
6
6
  @klass = Videojuicer::Campaign
7
7
  configure_test_settings
8
- Videojuicer.enter_scope :seed_name => fixtures.seed.name,
9
- :consumer_key=>fixtures["write-master"].consumer.consumer_key,
10
- :consumer_secret=>fixtures["write-master"].consumer.consumer_secret,
11
- :token=>fixtures["write-master"].authorized_token.oauth_token,
12
- :token_secret=>fixtures["write-master"].authorized_token.oauth_token_secret
13
- end
14
-
15
- after(:all) do
16
- Videojuicer.exit_scope
17
8
  end
18
9
 
19
10
  describe "instantiation" do
@@ -25,9 +16,6 @@ describe Videojuicer::Campaign do
25
16
  string_mash = (("A".."z").to_a + ("a".."z").to_a)
26
17
  @singular_name = "campaign"
27
18
  @plural_name = "campaigns"
28
- @good_attributes = {
29
- :name => (0..rand(75)).map{ string_mash[rand(string_mash.size - 1)] }.join
30
- }
31
19
  end
32
20
 
33
21
  it_should_behave_like "a RESTFUL resource model"
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), "..", "helpers", "spec_helper")
2
+
3
+ describe Videojuicer::Criterion::DateRange do
4
+
5
+ before(:all) do
6
+ @klass = Videojuicer::Criterion::DateRange
7
+ configure_test_settings
8
+ end
9
+
10
+ describe "instantiation" do
11
+ it_should_behave_like "a configurable"
12
+ end
13
+
14
+ describe "general interface:" do
15
+ before(:all) do
16
+ @singular_name = "criterion"
17
+ @plural_name = "criteria/date_range"
18
+ end
19
+
20
+ it_should_behave_like "a dependent non-resource object"
21
+ end
22
+
23
+ end
24
+
@@ -0,0 +1,23 @@
1
+ require File.join(File.dirname(__FILE__), "..", "helpers", "spec_helper")
2
+
3
+ describe Videojuicer::Criterion::Geolocation do
4
+
5
+ before(:all) do
6
+ @klass = Videojuicer::Criterion::Geolocation
7
+ configure_test_settings
8
+ end
9
+
10
+ describe "instantiation" do
11
+ it_should_behave_like "a configurable"
12
+ end
13
+
14
+ describe "general interface:" do
15
+ before(:all) do
16
+ @singular_name = "criterion"
17
+ @plural_name = "criteria/geolocation"
18
+ end
19
+
20
+ it_should_behave_like "a dependent non-resource object"
21
+ end
22
+
23
+ end