animoto 0.0.0.alpha9 → 0.1.0.beta0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +26 -13
- data/integration/test.rb +2 -3
- data/lib/animoto/assets/base.rb +29 -0
- data/lib/animoto/assets/footage.rb +34 -0
- data/lib/animoto/assets/image.rb +25 -0
- data/lib/animoto/assets/song.rb +27 -0
- data/lib/animoto/assets/title_card.rb +35 -0
- data/lib/animoto/callbacks/base.rb +45 -0
- data/lib/animoto/callbacks/directing.rb +7 -0
- data/lib/animoto/callbacks/directing_and_rendering.rb +7 -0
- data/lib/animoto/callbacks/rendering.rb +7 -0
- data/lib/animoto/client.rb +133 -80
- data/lib/animoto/http_engines/base.rb +40 -0
- data/lib/animoto/http_engines/curl_adapter.rb +17 -5
- data/lib/animoto/http_engines/net_http_adapter.rb +6 -4
- data/lib/animoto/http_engines/patron_adapter.rb +7 -2
- data/lib/animoto/http_engines/rest_client_adapter.rb +3 -3
- data/lib/animoto/http_engines/typhoeus_adapter.rb +4 -4
- data/lib/animoto/manifests/base.rb +18 -0
- data/lib/animoto/manifests/directing.rb +146 -0
- data/lib/animoto/manifests/directing_and_rendering.rb +51 -0
- data/lib/animoto/manifests/rendering.rb +71 -0
- data/lib/animoto/resources/base.rb +133 -0
- data/lib/animoto/resources/jobs/base.rb +61 -0
- data/lib/animoto/resources/jobs/directing.rb +27 -0
- data/lib/animoto/resources/jobs/directing_and_rendering.rb +28 -0
- data/lib/animoto/resources/jobs/rendering.rb +35 -0
- data/lib/animoto/resources/storyboard.rb +36 -0
- data/lib/animoto/resources/video.rb +50 -0
- data/lib/animoto/response_parsers/base.rb +44 -0
- data/lib/animoto/response_parsers/json_adapter.rb +8 -7
- data/lib/animoto/response_parsers/yajl_adapter.rb +9 -8
- data/lib/animoto/support/content_type.rb +49 -0
- data/lib/animoto/support/coverable.rb +31 -0
- data/lib/animoto/support/dynamic_class_loader.rb +166 -0
- data/lib/animoto/support/errors.rb +5 -0
- data/lib/animoto/support/standard_envelope.rb +66 -0
- data/lib/animoto/support/visual.rb +32 -0
- data/lib/animoto.rb +7 -1
- data/spec/animoto/assets/base_spec.rb +5 -0
- data/spec/animoto/{footage_spec.rb → assets/footage_spec.rb} +4 -4
- data/spec/animoto/{image_spec.rb → assets/image_spec.rb} +4 -4
- data/spec/animoto/{song_spec.rb → assets/song_spec.rb} +3 -3
- data/spec/animoto/{title_card_spec.rb → assets/title_card_spec.rb} +4 -4
- data/spec/animoto/callbacks/base_spec.rb +76 -0
- data/spec/animoto/callbacks/directing_and_rendering_spec.rb +5 -0
- data/spec/animoto/callbacks/directing_spec.rb +5 -0
- data/spec/animoto/callbacks/rendering_spec.rb +5 -0
- data/spec/animoto/client_spec.rb +29 -5
- data/spec/animoto/{http_engine_spec.rb → http_engines/base_spec.rb} +5 -5
- data/spec/animoto/{directing_and_rendering_manifest_spec.rb → manifests/directing_and_rendering_spec.rb} +3 -3
- data/spec/animoto/{directing_manifest_spec.rb → manifests/directing_spec.rb} +8 -8
- data/spec/animoto/{rendering_manifest_spec.rb → manifests/rendering_spec.rb} +7 -7
- data/spec/animoto/{resource_spec.rb → resources/base_spec.rb} +7 -7
- data/spec/animoto/{job_spec.rb → resources/jobs/base_spec.rb} +9 -5
- data/spec/animoto/{directing_and_rendering_job_spec.rb → resources/jobs/directing_and_rendering_spec.rb} +7 -7
- data/spec/animoto/{directing_job_spec.rb → resources/jobs/directing_spec.rb} +7 -7
- data/spec/animoto/{rendering_job_spec.rb → resources/jobs/rendering_spec.rb} +8 -8
- data/spec/animoto/resources/storyboard_spec.rb +8 -0
- data/spec/animoto/resources/video_spec.rb +5 -0
- data/spec/animoto/response_parsers/json_adapter_spec.rb +2 -2
- data/spec/animoto/response_parsers/yajl_adapter_spec.rb +2 -2
- data/spec/animoto/support/coverable_spec.rb +5 -0
- data/spec/animoto/support/standard_envelope_spec.rb +5 -0
- data/spec/animoto/support/visual_spec.rb +5 -0
- metadata +56 -48
- data/lib/animoto/asset.rb +0 -19
- data/lib/animoto/content_type.rb +0 -47
- data/lib/animoto/coverable.rb +0 -29
- data/lib/animoto/directing_and_rendering_job.rb +0 -19
- data/lib/animoto/directing_and_rendering_manifest.rb +0 -25
- data/lib/animoto/directing_job.rb +0 -18
- data/lib/animoto/directing_manifest.rb +0 -112
- data/lib/animoto/dynamic_class_loader.rb +0 -64
- data/lib/animoto/errors.rb +0 -3
- data/lib/animoto/footage.rb +0 -16
- data/lib/animoto/http_engine.rb +0 -34
- data/lib/animoto/image.rb +0 -16
- data/lib/animoto/job.rb +0 -37
- data/lib/animoto/manifest.rb +0 -14
- data/lib/animoto/rendering_job.rb +0 -24
- data/lib/animoto/rendering_manifest.rb +0 -37
- data/lib/animoto/resource.rb +0 -149
- data/lib/animoto/response_parser.rb +0 -38
- data/lib/animoto/song.rb +0 -14
- data/lib/animoto/standard_envelope.rb +0 -27
- data/lib/animoto/storyboard.rb +0 -22
- data/lib/animoto/title_card.rb +0 -26
- data/lib/animoto/video.rb +0 -29
- data/lib/animoto/visual.rb +0 -30
- data/spec/animoto/asset_spec.rb +0 -5
- data/spec/animoto/coverable_spec.rb +0 -5
- data/spec/animoto/standard_envelope_spec.rb +0 -5
- data/spec/animoto/storyboard_spec.rb +0 -8
- data/spec/animoto/video_spec.rb +0 -5
- data/spec/animoto/visual_spec.rb +0 -5
data/README.md
CHANGED
@@ -31,6 +31,19 @@ This document does not cover the details of the Animoto API itself. For such inf
|
|
31
31
|
<a name="getting_started_using_the_ruby_client"></a>
|
32
32
|
## Getting Started using the Ruby Client
|
33
33
|
|
34
|
+
### Installation
|
35
|
+
|
36
|
+
You can install the Animoto API Ruby Client either through [RubyGems](http://rubygems.org):
|
37
|
+
|
38
|
+
gem install animoto -v 0.1.0.alpha0 --pre
|
39
|
+
|
40
|
+
Or by cloning [the repository](http://github.com/animoto/animoto_api_client_ruby) on [GitHub](http://github.com/) and building it from source:
|
41
|
+
|
42
|
+
git clone git://github.com/animoto/animoto_api_client_ruby.git
|
43
|
+
cd animoto_api_client_ruby
|
44
|
+
gem build animoto.gemspec
|
45
|
+
gem install animoto-0.1.0.alpha0.gem
|
46
|
+
|
34
47
|
### Prerequisites
|
35
48
|
|
36
49
|
#### Readers of this document should be familiar with...
|
@@ -87,7 +100,7 @@ client and using HTTP callbacks for status updates.
|
|
87
100
|
# create a directing and rendering manifest with the video title and
|
88
101
|
# producer. Also include rendering parameters like resolution, framerate,
|
89
102
|
# and format.
|
90
|
-
manifest =
|
103
|
+
manifest = Manifests::DirectingAndRendering.new(
|
91
104
|
:title => "Amazing Title!",
|
92
105
|
:producer => "Fishy Joe",
|
93
106
|
:resolution => "720p",
|
@@ -96,13 +109,13 @@ client and using HTTP callbacks for status updates.
|
|
96
109
|
)
|
97
110
|
|
98
111
|
# Add some images, text, and footage to our manifest.
|
99
|
-
manifest << Image.new("http://website.com/picture.png")
|
100
|
-
manifest << Image.new("http://website.com/hooray.png", :spotlit => true)
|
101
|
-
manifest << TitleCard.new("Woohoo!", "Hooray for everything!")
|
102
|
-
manifest << Footage.new("http://website.com/movie.mp4", :duration => 3.5)
|
112
|
+
manifest << Assets::Image.new("http://website.com/picture.png")
|
113
|
+
manifest << Assets::Image.new("http://website.com/hooray.png", :spotlit => true)
|
114
|
+
manifest << Assets::TitleCard.new("Woohoo!", "Hooray for everything!")
|
115
|
+
manifest << Assets::Footage.new("http://website.com/movie.mp4", :duration => 3.5)
|
103
116
|
|
104
117
|
# Setup the soundtrack.
|
105
|
-
manifest << Song.new("http://website.com/song.mp3", :artist => "Fishy Joe")
|
118
|
+
manifest << Assets::Song.new("http://website.com/song.mp3", :artist => "Fishy Joe")
|
106
119
|
|
107
120
|
# Setup to get http callbacks for status notification (see below for
|
108
121
|
# polling example).
|
@@ -128,16 +141,16 @@ status.
|
|
128
141
|
|
129
142
|
# Create a directing manifest. The directing manifest controls the images
|
130
143
|
# and other visual elements that will be in our final video.
|
131
|
-
manifest =
|
144
|
+
manifest = Manifests::Directing.new(:title => "Amazing Title!")
|
132
145
|
|
133
146
|
# Add some images, text, and footage to our manifest.
|
134
|
-
manifest << Image.new("http://website.com/picture.png")
|
135
|
-
manifest << Image.new("http://website.com/hooray.png", :spotlit => true)
|
136
|
-
manifest << TitleCard.new("Woohoo!", "Hooray for everything!")
|
137
|
-
manifest << Footage.new("http://website.com/movie.mp4", :duration => 3.5)
|
147
|
+
manifest << Assets::Image.new("http://website.com/picture.png")
|
148
|
+
manifest << Assets::Image.new("http://website.com/hooray.png", :spotlit => true)
|
149
|
+
manifest << Assets::TitleCard.new("Woohoo!", "Hooray for everything!")
|
150
|
+
manifest << Assets::Footage.new("http://website.com/movie.mp4", :duration => 3.5)
|
138
151
|
|
139
152
|
# Setup the soundtrack.
|
140
|
-
manifest << Song.new("http://website.com/song.mp3")
|
153
|
+
manifest << Assets::Song.new("http://website.com/song.mp3")
|
141
154
|
|
142
155
|
# Request a new directing job by sending the API our directing manifest.
|
143
156
|
directing_job = client.direct!(manifest)
|
@@ -154,7 +167,7 @@ status.
|
|
154
167
|
|
155
168
|
# Now it's time to render the storyboard into a video. First we create
|
156
169
|
# a rendering manifest.
|
157
|
-
manifest =
|
170
|
+
manifest = Manifests::Rendering.new(storyboard, :resolution => "720p", :framerate => 24, :format => 'h264')
|
158
171
|
|
159
172
|
# Send the manifest to the API.
|
160
173
|
rendering_job = client.render!(manifest)
|
data/integration/test.rb
CHANGED
@@ -33,7 +33,7 @@ raise "Example code not found in README (expected at xpath '#{example_code_path}
|
|
33
33
|
code = code_node.text
|
34
34
|
|
35
35
|
puts "Replacing example credentials with valid ones"
|
36
|
-
code.sub!(/Client\.new\(.+\)/, %Q{Client.new("#{credentials[:key]}","#{credentials[:secret]}")})
|
36
|
+
code.sub!(/Client\.new\(.+\)/, %Q{Client.new("#{credentials[:key]}","#{credentials[:secret]}",:endpoint => "#{credentials[:endpoint]}")})
|
37
37
|
|
38
38
|
puts "Replacing example assets with valid ones"
|
39
39
|
code.gsub!(/Image\.new\(.+\)/) { %Q{Image.new("#{assets[:images].shift}")} }
|
@@ -46,5 +46,4 @@ puts "Executing example"
|
|
46
46
|
eval code
|
47
47
|
|
48
48
|
puts
|
49
|
-
puts "If you're seeing this, things should have worked fine!"
|
50
|
-
puts "Enjoy your video at #{video.download_url}"
|
49
|
+
puts "If you're seeing this, things should have worked fine!"
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Animoto
|
2
|
+
module Assets
|
3
|
+
|
4
|
+
# @abstract
|
5
|
+
class Base
|
6
|
+
|
7
|
+
# The URL of this asset.
|
8
|
+
# @return [String]
|
9
|
+
attr_accessor :source
|
10
|
+
|
11
|
+
# Creates a new asset.
|
12
|
+
#
|
13
|
+
# @param [String] source the URL of this asset
|
14
|
+
# @return [Assets::Base] the asset
|
15
|
+
def initialize source, options = {}
|
16
|
+
@source = source
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns a representation of this asset as a Hash. Used mainly for generating
|
20
|
+
# manifests.
|
21
|
+
#
|
22
|
+
# @return [Hash<String,Object>] this asset as a Hash
|
23
|
+
def to_hash
|
24
|
+
{ 'source_url' => @source }
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Animoto
|
2
|
+
module Assets
|
3
|
+
class Footage < Animoto::Assets::Base
|
4
|
+
include Support::Visual
|
5
|
+
include Support::Coverable
|
6
|
+
|
7
|
+
# Whether or not to mix the audio of this footage with the video's soundtrack.
|
8
|
+
# @return [Boolean]
|
9
|
+
attr_accessor :audio_mix
|
10
|
+
|
11
|
+
# The time in seconds of where to start extracting a clip from this footage to
|
12
|
+
# add to the video.
|
13
|
+
# @return [Float]
|
14
|
+
attr_accessor :start_time
|
15
|
+
|
16
|
+
# The duration in seconds of how long this footage should run in the video.
|
17
|
+
# @return [Float]
|
18
|
+
attr_accessor :duration
|
19
|
+
|
20
|
+
# Returns a representation of this Footage as a Hash.
|
21
|
+
#
|
22
|
+
# @return [Hash<String,Object>] this asset as a Hash
|
23
|
+
# @see Animoto::Support::Visual#to_hash
|
24
|
+
# @see Animoto::Assets::Base#to_hash
|
25
|
+
def to_hash
|
26
|
+
hash = super
|
27
|
+
hash['audio_mix'] = 'MIX' if audio_mix
|
28
|
+
hash['start_time'] = start_time if start_time
|
29
|
+
hash['duration'] = duration if duration
|
30
|
+
hash
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Animoto
|
2
|
+
module Assets
|
3
|
+
class Image < Animoto::Assets::Base
|
4
|
+
include Support::Visual
|
5
|
+
include Support::Coverable
|
6
|
+
|
7
|
+
# The EXIF rotation value for how this image should be rotated in the video.
|
8
|
+
# @return [Integer]
|
9
|
+
attr_accessor :rotation
|
10
|
+
|
11
|
+
# Returns a representation of this Image as a Hash.
|
12
|
+
#
|
13
|
+
# @return [Hash<String,Object>] this asset as a Hash
|
14
|
+
# @see Animoto::Support::Visual#to_hash
|
15
|
+
# @see Animoto::Assets::Base#to_hash
|
16
|
+
def to_hash
|
17
|
+
hash = super
|
18
|
+
hash['rotation'] = rotation if rotation
|
19
|
+
hash['spotlit'] = spotlit? unless @spotlit.nil?
|
20
|
+
hash['cover'] = cover? unless @cover.nil?
|
21
|
+
hash
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Animoto
|
2
|
+
module Assets
|
3
|
+
class Song < Animoto::Assets::Base
|
4
|
+
|
5
|
+
# The offset in seconds from the beginning denoting where to start
|
6
|
+
# using this song in the video.
|
7
|
+
# @return [Float]
|
8
|
+
attr_accessor :start_time
|
9
|
+
|
10
|
+
# The duration in seconds of how long this song should play.
|
11
|
+
# @return [Float]
|
12
|
+
attr_accessor :duration
|
13
|
+
|
14
|
+
# Returns a representation of this Song as a Hash.
|
15
|
+
#
|
16
|
+
# @return [Hash<String,Object>] this asset as a Hash
|
17
|
+
# @see Animoto::Assets::Base#to_hash
|
18
|
+
def to_hash
|
19
|
+
hash = super
|
20
|
+
hash['start_time'] = start_time if start_time
|
21
|
+
hash['duration'] = duration if duration
|
22
|
+
hash
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Animoto
|
2
|
+
module Assets
|
3
|
+
class TitleCard
|
4
|
+
include Support::Visual
|
5
|
+
|
6
|
+
# The main text of this title card.
|
7
|
+
# @return [String]
|
8
|
+
attr_accessor :title
|
9
|
+
|
10
|
+
# The secondary text of this title card.
|
11
|
+
# @return [String]
|
12
|
+
attr_accessor :subtitle
|
13
|
+
|
14
|
+
# Creates a new TitleCard.
|
15
|
+
#
|
16
|
+
# @param [String] title the main text
|
17
|
+
# @param [String] subtitle the secondary text
|
18
|
+
def initialize title, subtitle = nil
|
19
|
+
@title, @subtitle = title, subtitle
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns a representation of this TitleCard as a Hash.
|
23
|
+
#
|
24
|
+
# @return [Hash<String,Object>] this TitleCard as a Hash
|
25
|
+
# @see Animoto::Support::Visual#to_hash
|
26
|
+
def to_hash
|
27
|
+
hash = super
|
28
|
+
hash['h1'] = title
|
29
|
+
hash['h2'] = subtitle if subtitle
|
30
|
+
hash['spotlit'] = spotlit? unless @spotlit.nil?
|
31
|
+
hash
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Animoto
|
2
|
+
module Callbacks
|
3
|
+
|
4
|
+
# @abstract
|
5
|
+
class Base
|
6
|
+
include Support::StandardEnvelope
|
7
|
+
|
8
|
+
# @return [String]
|
9
|
+
# @see Animoto::Support::StandardEnvelope::ClassMethods#payload_key
|
10
|
+
def self.payload_key
|
11
|
+
super + '_callback'
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Hash<Symbol,Object>]
|
15
|
+
# @see Animoto::Support::StandardEnvelope::ClassMethods#unpack_standard_envelope
|
16
|
+
def self.unpack_standard_envelope body = {}
|
17
|
+
super.merge({ :state => body['response']['payload'][payload_key]['state'] })
|
18
|
+
end
|
19
|
+
|
20
|
+
# The state of the job when it completed.
|
21
|
+
# @return [String]
|
22
|
+
attr_reader :state
|
23
|
+
|
24
|
+
# Errors for the job.
|
25
|
+
# @return [Array<Animoto::Error>]
|
26
|
+
attr_reader :errors
|
27
|
+
|
28
|
+
# The url for this job.
|
29
|
+
# @return [String]
|
30
|
+
attr_reader :url
|
31
|
+
|
32
|
+
# Creates a new Callback.
|
33
|
+
#
|
34
|
+
# @param [String] body the request body of the HTTP callback
|
35
|
+
# @return [Callbacks::Base] the Callback
|
36
|
+
def initialize body
|
37
|
+
params = unpack_standard_envelope(body)
|
38
|
+
@state = params[:state]
|
39
|
+
@errors = params[:errors].collect { |e| Animoto::Error.new(e['message']) }
|
40
|
+
@url = params[:url]
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/animoto/client.rb
CHANGED
@@ -2,30 +2,39 @@ require 'yaml'
|
|
2
2
|
require 'uri'
|
3
3
|
require 'logger'
|
4
4
|
|
5
|
-
require 'animoto/
|
6
|
-
require 'animoto/
|
7
|
-
require 'animoto/
|
8
|
-
require 'animoto/
|
9
|
-
require 'animoto/
|
10
|
-
require 'animoto/visual'
|
11
|
-
|
12
|
-
require 'animoto/
|
13
|
-
require 'animoto/
|
14
|
-
require 'animoto/
|
15
|
-
require 'animoto/
|
16
|
-
require 'animoto/
|
17
|
-
require 'animoto/
|
18
|
-
require 'animoto/
|
19
|
-
|
20
|
-
require 'animoto/
|
21
|
-
require 'animoto/
|
22
|
-
require 'animoto/
|
23
|
-
require 'animoto/
|
24
|
-
require 'animoto/
|
25
|
-
|
26
|
-
require 'animoto/
|
27
|
-
require 'animoto/
|
28
|
-
require 'animoto/
|
5
|
+
require 'animoto/support/content_type'
|
6
|
+
require 'animoto/support/coverable'
|
7
|
+
require 'animoto/support/dynamic_class_loader'
|
8
|
+
require 'animoto/support/errors'
|
9
|
+
require 'animoto/support/standard_envelope'
|
10
|
+
require 'animoto/support/visual'
|
11
|
+
|
12
|
+
require 'animoto/resources/base'
|
13
|
+
require 'animoto/resources/storyboard'
|
14
|
+
require 'animoto/resources/video'
|
15
|
+
require 'animoto/resources/jobs/base'
|
16
|
+
require 'animoto/resources/jobs/directing_and_rendering'
|
17
|
+
require 'animoto/resources/jobs/directing'
|
18
|
+
require 'animoto/resources/jobs/rendering'
|
19
|
+
|
20
|
+
require 'animoto/assets/base'
|
21
|
+
require 'animoto/assets/footage'
|
22
|
+
require 'animoto/assets/image'
|
23
|
+
require 'animoto/assets/song'
|
24
|
+
require 'animoto/assets/title_card'
|
25
|
+
|
26
|
+
require 'animoto/manifests/base'
|
27
|
+
require 'animoto/manifests/directing'
|
28
|
+
require 'animoto/manifests/directing_and_rendering'
|
29
|
+
require 'animoto/manifests/rendering'
|
30
|
+
|
31
|
+
require 'animoto/callbacks/base'
|
32
|
+
require 'animoto/callbacks/directing'
|
33
|
+
require 'animoto/callbacks/directing_and_rendering'
|
34
|
+
require 'animoto/callbacks/rendering'
|
35
|
+
|
36
|
+
require 'animoto/http_engines/base'
|
37
|
+
require 'animoto/response_parsers/base'
|
29
38
|
|
30
39
|
module Animoto
|
31
40
|
class Client
|
@@ -33,8 +42,54 @@ module Animoto
|
|
33
42
|
API_VERSION = 1
|
34
43
|
BASE_CONTENT_TYPE = "application/vnd.animoto"
|
35
44
|
|
36
|
-
|
37
|
-
|
45
|
+
# Your API key.
|
46
|
+
# @return [String]
|
47
|
+
attr_accessor :key
|
48
|
+
|
49
|
+
# Your API secret.
|
50
|
+
# @return [String]
|
51
|
+
attr_accessor :secret
|
52
|
+
|
53
|
+
# The base URL where all requests will be sent.
|
54
|
+
# @return [String]
|
55
|
+
attr_accessor :endpoint
|
56
|
+
|
57
|
+
# A logger.
|
58
|
+
# @return [Logger]
|
59
|
+
attr_accessor :logger
|
60
|
+
|
61
|
+
# The engine to handle HTTP requests.
|
62
|
+
# @return [HTTPEngines::Base]
|
63
|
+
# @overload http_engine
|
64
|
+
# Returns the HTTP engine.
|
65
|
+
# @return [HTTPEngines::Base]
|
66
|
+
# @overload http_engine=(engine)
|
67
|
+
# Sets the HTTP engine.
|
68
|
+
#
|
69
|
+
# @param [HTTPEngines::Base,Symbol,Class] engine you may pass a
|
70
|
+
# HTTPEngine instance to use, or the symbolic name of an adapter to use,
|
71
|
+
# or a Class whose instances respond to #request and return a String of
|
72
|
+
# the response body
|
73
|
+
# @see Animoto::HTTPEngines::Base
|
74
|
+
# @return [HTTPEngines::Base] the engine instance
|
75
|
+
# @raise [ArgumentError] if given a class without the correct interface
|
76
|
+
attr_reader :http_engine
|
77
|
+
|
78
|
+
# The engine to handle parsing XML or JSON responses.
|
79
|
+
# @return [ResponseParsers::Base]
|
80
|
+
# @overload response_parser
|
81
|
+
# Returns the parser.
|
82
|
+
# @return [ResponseParsers::Base]
|
83
|
+
# @overload response_parser=(parser)
|
84
|
+
# Sets the parser.
|
85
|
+
#
|
86
|
+
# @param [ResponseParsers::Base,Symbol,Class] parser you may pass a
|
87
|
+
# ResponseParser instance to use, or the symbolic name of an adapter to use,
|
88
|
+
# or a Class whose instances respond to #parse, #unparse, and #format.
|
89
|
+
# @see Animoto::ResponseParsers::Base
|
90
|
+
# @return [ResponseParsers::Base] the parser instance
|
91
|
+
# @raise [ArgumentError] if given a class without the correct interface
|
92
|
+
attr_reader :response_parser
|
38
93
|
|
39
94
|
# Creates a new Client object which handles credentials, versioning, making requests, and
|
40
95
|
# parsing responses.
|
@@ -60,18 +115,9 @@ module Animoto
|
|
60
115
|
__send__ :response_parser=, options[:response_parser] || :json
|
61
116
|
end
|
62
117
|
|
63
|
-
# Set the HTTP engine this client will use.
|
64
|
-
#
|
65
|
-
# @param [HTTPEngine, Symbol, Class] engine you may pass a
|
66
|
-
# HTTPEngine instance to use, or the symbolic name of a adapter to use,
|
67
|
-
# or a Class whose instances respond to #request and return a String of
|
68
|
-
# the response body
|
69
|
-
# @see Animoto::HTTPEngine
|
70
|
-
# @return [HTTPEngine] the engine instance
|
71
|
-
# @raise [ArgumentError] if given a class without the correct interface
|
72
118
|
def http_engine= engine
|
73
119
|
@http_engine = case engine
|
74
|
-
when Animoto::
|
120
|
+
when Animoto::HTTPEngines::Base
|
75
121
|
engine
|
76
122
|
when Class
|
77
123
|
if engine.instance_methods.include?('request')
|
@@ -80,21 +126,13 @@ module Animoto
|
|
80
126
|
raise ArgumentError
|
81
127
|
end
|
82
128
|
else
|
83
|
-
Animoto::
|
129
|
+
Animoto::HTTPEngines[engine].new
|
84
130
|
end
|
85
131
|
end
|
86
132
|
|
87
|
-
# Set the response parser this client will use.
|
88
|
-
#
|
89
|
-
# @param [ResponseParser, Symbol, Class] parser you may pass a
|
90
|
-
# ResponseParser instance to use, or the symbolic name of a adapter to use,
|
91
|
-
# or a Class whose instances respond to #parse, #unparse, and #format.
|
92
|
-
# @see Animoto::ResponseParser
|
93
|
-
# @return [ResponseParser] the parser instance
|
94
|
-
# @raise [ArgumentError] if given a class without the correct interface
|
95
133
|
def response_parser= parser
|
96
134
|
@response_parser = case parser
|
97
|
-
when Animoto::
|
135
|
+
when Animoto::ResponseParsers::Base
|
98
136
|
parser
|
99
137
|
when Class
|
100
138
|
if %{format parse unparse}.all? { |m| parser.instance_methods.include? m }
|
@@ -103,53 +141,62 @@ module Animoto
|
|
103
141
|
raise ArgumentError
|
104
142
|
end
|
105
143
|
else
|
106
|
-
Animoto::
|
144
|
+
Animoto::ResponseParsers[parser].new
|
107
145
|
end
|
108
146
|
end
|
109
147
|
|
110
148
|
# Finds a resource by its URL.
|
111
149
|
#
|
112
|
-
# @param [Class] klass the
|
150
|
+
# @param [Class] klass the resource class you're finding
|
113
151
|
# @param [String] url the URL of the resource you want
|
114
|
-
# @param [Hash] options
|
115
|
-
# @return [
|
152
|
+
# @param [Hash<Symbol,Object>] options
|
153
|
+
# @return [Resources::Base] the resource object found
|
116
154
|
def find klass, url, options = {}
|
117
155
|
klass.load(find_request(klass, url, options))
|
118
156
|
end
|
119
157
|
|
158
|
+
# Returns a callback object of the specified type given the callback body.
|
159
|
+
#
|
160
|
+
# @param [Class] klass the callback class
|
161
|
+
# @param [String] body the HTTP body of the callback
|
162
|
+
# @return [Callbacks::Base] the callback object
|
163
|
+
def process_callback klass, body
|
164
|
+
klass.new(response_parser.parse(body))
|
165
|
+
end
|
166
|
+
|
120
167
|
# Sends a request to start directing a storyboard.
|
121
168
|
#
|
122
|
-
# @param [
|
123
|
-
# @param [Hash] options
|
124
|
-
# @return [
|
169
|
+
# @param [Manifests::Directing] manifest the manifest to direct
|
170
|
+
# @param [Hash<Symbol,Object>] options
|
171
|
+
# @return [Jobs::Directing] a job to monitor the status of the directing
|
125
172
|
def direct! manifest, options = {}
|
126
|
-
|
173
|
+
Resources::Jobs::Directing.load(send_manifest(manifest, Resources::Jobs::Directing.endpoint, options))
|
127
174
|
end
|
128
175
|
|
129
176
|
# Sends a request to start rendering a video.
|
130
177
|
#
|
131
|
-
# @param [
|
132
|
-
# @param [Hash] options
|
133
|
-
# @return [
|
178
|
+
# @param [Manifests::Rendering] manifest the manifest to render
|
179
|
+
# @param [Hash<Symbol,Object>] options
|
180
|
+
# @return [Jobs::Rendering] a job to monitor the status of the rendering
|
134
181
|
def render! manifest, options = {}
|
135
|
-
|
182
|
+
Resources::Jobs::Rendering.load(send_manifest(manifest, Resources::Jobs::Rendering.endpoint, options))
|
136
183
|
end
|
137
184
|
|
138
185
|
# Sends a request to start directing and rendering a video.
|
139
186
|
#
|
140
|
-
# @param [
|
141
|
-
# @param [Hash] options
|
142
|
-
# @return [
|
187
|
+
# @param [Manifests::DirectingAndRendering] manifest the manifest to direct and render
|
188
|
+
# @param [Hash<Symbol,Object>] options
|
189
|
+
# @return [Jobs::DirectingAndRendering] a job to monitor the status of the directing and rendering
|
143
190
|
def direct_and_render! manifest, options = {}
|
144
|
-
|
191
|
+
Resources::Jobs::DirectingAndRendering.load(send_manifest(manifest, Resources::Jobs::DirectingAndRendering.endpoint, options))
|
145
192
|
end
|
146
193
|
|
147
194
|
# Update a resource with the latest attributes. Useful to update the state of a Job to
|
148
195
|
# see if it's ready if you are not using HTTP callbacks.
|
149
196
|
#
|
150
|
-
# @param [
|
151
|
-
# @param [Hash] options
|
152
|
-
# @return [
|
197
|
+
# @param [Resources::Base] resource the resource to update
|
198
|
+
# @param [Hash<Symbol,Object>] options
|
199
|
+
# @return [Resources::Base] the given resource with the latest attributes
|
153
200
|
def reload! resource, options = {}
|
154
201
|
resource.load(find_request(resource.class, resource.url, options))
|
155
202
|
end
|
@@ -159,6 +206,7 @@ module Animoto
|
|
159
206
|
# Sets the API credentials from an .animotorc file. First looks for one in the current
|
160
207
|
# directory, then checks ~/.animotorc, then finally /etc/.animotorc.
|
161
208
|
#
|
209
|
+
# @return [void]
|
162
210
|
# @raise [ArgumentError] if none of the files are found
|
163
211
|
def configure_from_rc_file
|
164
212
|
current_path = Dir.pwd + '/.animotorc'
|
@@ -183,18 +231,18 @@ module Animoto
|
|
183
231
|
#
|
184
232
|
# @param [Class] klass the Resource class you're looking for
|
185
233
|
# @param [String] url the URL of the resource
|
186
|
-
# @param [Hash] options
|
187
|
-
# @return [Hash] deserialized response body
|
234
|
+
# @param [Hash<Symbol,Object>] options
|
235
|
+
# @return [Hash<String,Object>] deserialized response body
|
188
236
|
def find_request klass, url, options = {}
|
189
237
|
request(:get, url, nil, { "Accept" => content_type_of(klass) }, options)
|
190
238
|
end
|
191
239
|
|
192
240
|
# Builds a request requiring a manifest.
|
193
241
|
#
|
194
|
-
# @param [
|
242
|
+
# @param [Manifests::Base] manifest the manifest being acted on
|
195
243
|
# @param [String] endpoint the endpoint to send the request to
|
196
|
-
# @param [Hash] options
|
197
|
-
# @return [Hash] deserialized response body
|
244
|
+
# @param [Hash<Symbol,Object>] options
|
245
|
+
# @return [Hash<String,Object>] deserialized response body
|
198
246
|
def send_manifest manifest, endpoint, options = {}
|
199
247
|
u = URI.parse(self.endpoint)
|
200
248
|
u.path = endpoint
|
@@ -211,25 +259,30 @@ module Animoto
|
|
211
259
|
#
|
212
260
|
# @param [Symbol] method which HTTP method to use (should be lowercase, i.e. :get instead of :GET)
|
213
261
|
# @param [String] url the URL of the request
|
214
|
-
# @param [String,
|
262
|
+
# @param [String,nil] body the request body
|
215
263
|
# @param [Hash<String,String>] headers the request headers (will be sent as-is, which means you should
|
216
264
|
# specify "Content-Type" => "..." instead of, say, :content_type => "...")
|
217
|
-
# @param [Hash] options
|
218
|
-
# @return [Hash] deserialized response body
|
265
|
+
# @param [Hash<Symbol,Object>] options
|
266
|
+
# @return [Hash<String,Object>] deserialized response body
|
219
267
|
# @raise [Error]
|
220
268
|
def request method, url, body, headers = {}, options = {}
|
221
|
-
|
269
|
+
code, body = catch(:fail) do
|
222
270
|
options = { :username => @key, :password => @secret }.merge(options)
|
223
271
|
@logger.info "Sending request to #{url.inspect} with body #{body}"
|
224
272
|
response = http_engine.request(method, url, body, headers, options)
|
225
273
|
@logger.info "Received response #{response}"
|
226
274
|
return response_parser.parse(response)
|
227
275
|
end
|
228
|
-
if
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
276
|
+
if code
|
277
|
+
if body.empty?
|
278
|
+
@logger.error "HTTP error (#{code})"
|
279
|
+
raise Animoto::Error.new("HTTP error (#{code})")
|
280
|
+
else
|
281
|
+
errors = response_parser.parse(body)['response']['status']['errors']
|
282
|
+
err_string = errors.collect { |e| e['message'] }.join(', ')
|
283
|
+
@logger.error "Error response from server: #{err_string}"
|
284
|
+
raise Animoto::Error.new(err_string)
|
285
|
+
end
|
233
286
|
else
|
234
287
|
@logger.error "Error sending request to #{url.inspect}"
|
235
288
|
raise Animoto::Error
|
@@ -240,7 +293,7 @@ module Animoto
|
|
240
293
|
end
|
241
294
|
|
242
295
|
# Creates the full content type string given a Resource class or instance
|
243
|
-
# @param [Class,ContentType] klass_or_instance the class or instance to build the
|
296
|
+
# @param [Class,Support::ContentType] klass_or_instance the class or instance to build the
|
244
297
|
# content type for
|
245
298
|
# @return [String] the full content type with the version and format included (i.e.
|
246
299
|
# "application/vnd.animoto.storyboard-v1+json")
|