animoto 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +95 -27
- data/lib/animoto/client.rb +48 -26
- data/lib/animoto/http_engines/base.rb +2 -14
- data/lib/animoto/http_engines/curl_adapter.rb +11 -2
- data/lib/animoto/http_engines/net_http_adapter.rb +15 -7
- data/lib/animoto/http_engines/patron_adapter.rb +1 -2
- data/lib/animoto/http_engines/rest_client_adapter.rb +2 -2
- data/lib/animoto/http_engines/typhoeus_adapter.rb +4 -3
- data/lib/animoto/manifests/base.rb +53 -3
- data/lib/animoto/manifests/directing.rb +6 -19
- data/lib/animoto/manifests/directing_and_rendering.rb +6 -19
- data/lib/animoto/manifests/rendering.rb +3 -16
- data/lib/animoto/manifests/storyboard_bundling.rb +40 -0
- data/lib/animoto/manifests/storyboard_unbundling.rb +39 -0
- data/lib/animoto/resources/base.rb +2 -2
- data/lib/animoto/resources/jobs/base.rb +8 -0
- data/lib/animoto/resources/jobs/directing.rb +0 -2
- data/lib/animoto/resources/jobs/directing_and_rendering.rb +0 -2
- data/lib/animoto/resources/jobs/rendering.rb +0 -2
- data/lib/animoto/resources/jobs/storyboard_bundling.rb +29 -0
- data/lib/animoto/resources/jobs/storyboard_unbundling.rb +34 -0
- data/lib/animoto/support/content_type.rb +1 -1
- data/lib/animoto/support/dynamic_class_loader.rb +1 -1
- data/lib/animoto/support/errors.rb +29 -0
- data/lib/animoto/support/hash.rb +2 -2
- data/lib/animoto/support/standard_envelope.rb +4 -2
- data/lib/animoto/support/string.rb +2 -2
- data/lib/animoto/support/visual.rb +1 -1
- data/lib/animoto.rb +1 -1
- data/spec/animoto/client_spec.rb +221 -9
- data/spec/animoto/http_engines/base_spec.rb +1 -14
- data/spec/animoto/manifests/rendering_spec.rb +1 -1
- data/spec/animoto/manifests/storyboard_bundling_spec.rb +73 -0
- data/spec/animoto/manifests/storyboard_unbundling_spec.rb +71 -0
- data/spec/animoto/resources/base_spec.rb +2 -2
- data/spec/animoto/resources/jobs/storyboard_bundling_spec.rb +43 -0
- data/spec/animoto/resources/jobs/storyboard_unbundling_spec.rb +48 -0
- data/spec/spec_helper.rb +4 -3
- metadata +14 -7
- data/integration/test.rb +0 -49
data/README.md
CHANGED
@@ -156,8 +156,8 @@ status.
|
|
156
156
|
|
157
157
|
# Poll the service until the directing job is done.
|
158
158
|
while directing_job.pending?
|
159
|
-
|
160
|
-
|
159
|
+
sleep(30)
|
160
|
+
client.reload!(directing_job)
|
161
161
|
end
|
162
162
|
|
163
163
|
# If the directing job finished successfully, there will be a "storyboard"
|
@@ -166,37 +166,105 @@ status.
|
|
166
166
|
|
167
167
|
# Now it's time to render the storyboard into a video. First we create
|
168
168
|
# a rendering manifest.
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
169
|
+
manifest = Manifests::Rendering.new(
|
170
|
+
storyboard,
|
171
|
+
:resolution => "720p",
|
172
|
+
:framerate => 24,
|
173
|
+
:format => 'h264'
|
174
|
+
)
|
175
|
+
|
176
|
+
# Send the manifest to the API.
|
177
|
+
rendering_job = client.render!(manifest)
|
178
|
+
|
179
|
+
# Poll the service until the rendering job is done
|
180
|
+
while rendering_job.pending?
|
181
|
+
sleep(30)
|
182
|
+
client.reload!(rendering_job)
|
183
|
+
end
|
184
184
|
|
185
185
|
# If the job has a video associated with it, everything worked out ok.
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
186
|
+
if video = rendering_job.video
|
187
|
+
# Print a link to download the video file.
|
188
|
+
client.reload!(video)
|
189
|
+
puts video.download_url
|
190
|
+
else
|
191
|
+
# Something happened during rendering...
|
192
|
+
raise rendering_job.errors.first
|
193
|
+
end
|
194
194
|
else
|
195
195
|
# Looks like there was a problem. Perhaps one of the assets wasn't
|
196
196
|
# retrieved or was corrupt...
|
197
|
-
|
197
|
+
raise directing_job.errors.first
|
198
198
|
end
|
199
199
|
|
200
|
+
### Storyboard bundling example
|
201
|
+
|
202
|
+
Bundling is a process used for exporting an Animoto storyboard. The bundling process packages
|
203
|
+
up all the information used by Animoto to render videos into a single file, the storyboard
|
204
|
+
bundle. This file is essentially just a zip file with a special structure. After a storyboard
|
205
|
+
bundle has been created and retrieved by your system, the original storyboard can be deleted.
|
206
|
+
Later, the storyboard bundle can be reconstituted into an Animoto storyboard so that videos may
|
207
|
+
be rendered.
|
208
|
+
|
209
|
+
require 'animoto/client'
|
210
|
+
include Animoto
|
211
|
+
|
212
|
+
client = Client.new("key", "secret")
|
213
|
+
|
214
|
+
# Make a directing manifest and direct it as detailed above.
|
215
|
+
# Afterwards, we can make a StoryboardBundling manifest and bundle up the
|
216
|
+
# storyboard we just made.
|
217
|
+
|
218
|
+
storyboard = directing_job.storyboard
|
219
|
+
bundling_manifest = Manifests::StoryboardBundling.new(storyboard)
|
220
|
+
bundling_job = client.bundle!(bundling_manifest)
|
221
|
+
|
222
|
+
# Poll the service until the bundling job is complete.
|
223
|
+
# As with all jobs, HTTP callbacks are also supported, but we're just
|
224
|
+
# going for a simple example here.
|
225
|
+
while bundling_job.pending?
|
226
|
+
sleep(30)
|
227
|
+
client.reload!(bundling_job)
|
228
|
+
end
|
229
|
+
|
230
|
+
# The bundle_url returned points to where you can download the storyboard
|
231
|
+
# bundle. Downloading the bundle and archiving it elsewhere is outside the
|
232
|
+
# scope of the client's functionality.
|
233
|
+
puts bundling_job.bundle_url
|
234
|
+
|
235
|
+
# After you have a handle for the storyboard bundle, the original storyboard
|
236
|
+
# can be deleted.
|
237
|
+
client.delete!(storyboard)
|
238
|
+
|
239
|
+
Turning a bundle back into a storyboard is just as simple.
|
240
|
+
|
241
|
+
require 'animoto/client'
|
242
|
+
include Animoto
|
243
|
+
|
244
|
+
client = Client.new("key", "secret")
|
245
|
+
|
246
|
+
# Make a storyboard unbundling manifest with the url to your archived storyboard bundle.
|
247
|
+
unbundling_manifest = Manifest::StoryboardUnbundling.new(:bundle_url => "http://your-storage-solution.com/path/to/your/bundle")
|
248
|
+
unbundling_job = client.unbundle!(unbundling_manifest)
|
249
|
+
|
250
|
+
# Poll the service until unbundling is complete.
|
251
|
+
while unbundling_job.pending?
|
252
|
+
sleep(30)
|
253
|
+
client.reload!(unbundling_job)
|
254
|
+
end
|
255
|
+
|
256
|
+
# Now you can use the storyboard to render a video.
|
257
|
+
rendering_manifest = Manifests::Rendering.new(
|
258
|
+
unbundling_job.storyboard,
|
259
|
+
:resolution => "720p",
|
260
|
+
:framerate => 24,
|
261
|
+
:format => 'h264'
|
262
|
+
)
|
263
|
+
rendering_job = client.render!(rendering_manifest)
|
264
|
+
|
265
|
+
# Now proceed with using your render as detailed above.
|
266
|
+
|
267
|
+
|
200
268
|
<a name="how_to_contribute"></a>
|
201
269
|
## How to contribute to this client
|
202
270
|
|
@@ -229,4 +297,4 @@ IN NO EVENT SHALL ANIMOTO BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY SPECIAL, P
|
|
229
297
|
|
230
298
|
You agree to indemnify defend and hold Animoto, its parents, subsidiaries, affiliates, officers and employees, harmless from any liabilities, claims, expenses or demands, including reasonable attorneys’ fees and costs, made by any third party due to or arising out of your use of this software, derivative works created by you, the violation of laws, rules, regulations or these terms, and the infringement of any intellectual property right by your derivative works or by you.
|
231
299
|
|
232
|
-
[api_docs]: http://animoto.com/
|
300
|
+
[api_docs]: http://api-documentation.animoto.com/index.html
|
data/lib/animoto/client.rb
CHANGED
@@ -18,6 +18,8 @@ require 'animoto/resources/jobs/base'
|
|
18
18
|
require 'animoto/resources/jobs/directing_and_rendering'
|
19
19
|
require 'animoto/resources/jobs/directing'
|
20
20
|
require 'animoto/resources/jobs/rendering'
|
21
|
+
require 'animoto/resources/jobs/storyboard_bundling'
|
22
|
+
require 'animoto/resources/jobs/storyboard_unbundling'
|
21
23
|
|
22
24
|
require 'animoto/assets/base'
|
23
25
|
require 'animoto/assets/footage'
|
@@ -29,6 +31,8 @@ require 'animoto/manifests/base'
|
|
29
31
|
require 'animoto/manifests/directing'
|
30
32
|
require 'animoto/manifests/directing_and_rendering'
|
31
33
|
require 'animoto/manifests/rendering'
|
34
|
+
require 'animoto/manifests/storyboard_bundling'
|
35
|
+
require 'animoto/manifests/storyboard_unbundling'
|
32
36
|
|
33
37
|
require 'animoto/http_engines/base'
|
34
38
|
require 'animoto/response_parsers/base'
|
@@ -37,7 +41,7 @@ module Animoto
|
|
37
41
|
class Client
|
38
42
|
|
39
43
|
# The default endpoint where requests go.
|
40
|
-
API_ENDPOINT = "https://
|
44
|
+
API_ENDPOINT = "https://platform-sandbox.animoto.com/"
|
41
45
|
|
42
46
|
# The version of the Animoto API this client targets.
|
43
47
|
API_VERSION = 1
|
@@ -185,6 +189,24 @@ module Animoto
|
|
185
189
|
Resources::Jobs::DirectingAndRendering.load(send_manifest(manifest, Resources::Jobs::DirectingAndRendering.endpoint, options))
|
186
190
|
end
|
187
191
|
|
192
|
+
# Sends a request to bundle a storyboard.
|
193
|
+
#
|
194
|
+
# @param [Manifests::StoryboardBundling] manifest the manifest to bundle
|
195
|
+
# @param [Hash{Symbol=>Object}] options
|
196
|
+
# @return [Jobs::StoryboardBundling] a job to monitor the status of the storyboard bundling
|
197
|
+
def bundle! manifest, options = {}
|
198
|
+
Resources::Jobs::StoryboardBundling.load(send_manifest(manifest, Resources::Jobs::StoryboardBundling.endpoint, options))
|
199
|
+
end
|
200
|
+
|
201
|
+
# Sends a request to unbundle a storyboard.
|
202
|
+
#
|
203
|
+
# @param [Manifests::StoryboardUnbundling] manifest the manifest to unbundle
|
204
|
+
# @param [Hash{Symbol=>Object}] options
|
205
|
+
# @return [Jobs::StoryboardUnbundling] a job to monitor the status of the storyboard unbundling
|
206
|
+
def unbundle! manifest, options = {}
|
207
|
+
Resources::Jobs::StoryboardUnbundling.load(send_manifest(manifest, Resources::Jobs::StoryboardUnbundling.endpoint, options))
|
208
|
+
end
|
209
|
+
|
188
210
|
# Update a resource with the latest attributes. Useful to update the state of a Job to
|
189
211
|
# see if it's ready if you are not using HTTP callbacks.
|
190
212
|
#
|
@@ -195,6 +217,15 @@ module Animoto
|
|
195
217
|
resource.load(find_request(resource.class, resource.url, options))
|
196
218
|
end
|
197
219
|
|
220
|
+
# Delete a resource. May not supported for all types of resources.
|
221
|
+
#
|
222
|
+
# @param [Resources::Base] resource to delete
|
223
|
+
# @param [Hash{Symbol=>Object}] options
|
224
|
+
# @return [Boolean] true if deletion was successful
|
225
|
+
def delete! resource, options = {}
|
226
|
+
request(:delete, resource.url, nil)
|
227
|
+
end
|
228
|
+
|
198
229
|
private
|
199
230
|
|
200
231
|
# Sets the API credentials from an .animotorc file. First looks for one in the current
|
@@ -208,7 +239,6 @@ module Animoto
|
|
208
239
|
config = if File.exist?(current_path)
|
209
240
|
YAML.load(File.read(current_path))
|
210
241
|
elsif File.exist?(home_path)
|
211
|
-
home_path = File.expand_path '~/.animotorc'
|
212
242
|
YAML.load(File.read(home_path))
|
213
243
|
elsif File.exist?('/etc/.animotorc')
|
214
244
|
YAML.load(File.read('/etc/.animotorc'))
|
@@ -244,7 +274,7 @@ module Animoto
|
|
244
274
|
:post,
|
245
275
|
u.to_s,
|
246
276
|
response_parser.unparse(manifest.to_hash),
|
247
|
-
{ "Accept" =>
|
277
|
+
{ "Accept" => content_type_of(manifest.associated_job_class), "Content-Type" => content_type_of(manifest) },
|
248
278
|
options
|
249
279
|
)
|
250
280
|
end
|
@@ -257,33 +287,25 @@ module Animoto
|
|
257
287
|
# @param [Hash{String=>String}] headers the request headers (will be sent as-is, which means you should
|
258
288
|
# specify "Content-Type" => "..." instead of, say, :content_type => "...")
|
259
289
|
# @param [Hash{Symbol=>Object}] options
|
260
|
-
# @return [Hash{String=>Object}] deserialized response body
|
261
|
-
# @raise [
|
290
|
+
# @return [Hash{String=>Object},Boolean] deserialized response body, or boolean indicating success or failure
|
291
|
+
# @raise [HTTPError] if something goes wrong with the request or response
|
262
292
|
def request method, url, body, headers = {}, options = {}
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
293
|
+
options = { :username => @key, :password => @secret }.merge(options)
|
294
|
+
@logger.info "Sending request to #{url.inspect} with body #{body}"
|
295
|
+
code, response_body = http_engine.request(method, url, body, headers, options)
|
296
|
+
if method == :head
|
297
|
+
(200..299) === code || raise(Animoto::HTTPError.new(url, code))
|
298
|
+
else
|
299
|
+
case code
|
300
|
+
when 204, 205
|
301
|
+
true
|
302
|
+
when (200..299)
|
303
|
+
response_parser.parse(response_body)
|
274
304
|
else
|
275
|
-
|
276
|
-
|
277
|
-
@logger.error "Error response from server: #{err_string}"
|
278
|
-
raise Animoto::Error.new(err_string)
|
305
|
+
parsed_response = begin response_body ? response_parser.parse(response_body) : nil rescue nil end
|
306
|
+
raise Animoto::HTTPError.new(url, code, parsed_response)
|
279
307
|
end
|
280
|
-
else
|
281
|
-
@logger.error "Error sending request to #{url.inspect}"
|
282
|
-
raise Animoto::Error
|
283
308
|
end
|
284
|
-
rescue NoMethodError => e
|
285
|
-
@logger.error e.inspect
|
286
|
-
raise Animoto::Error.new("Invalid response (#{e.inspect})")
|
287
309
|
end
|
288
310
|
|
289
311
|
# Creates the full content type string given a Resource class or instance
|
@@ -26,23 +26,11 @@ module Animoto
|
|
26
26
|
# @option options [Integer] :timeout set a timeout
|
27
27
|
# @option options [String] :username the authentication username
|
28
28
|
# @option options [String] :password the authentication password
|
29
|
-
# @return [String]
|
29
|
+
# @return [Array[Integer,String]] array of status code and response body
|
30
30
|
# @raise [AbstractMethodError] if called on the abstract class
|
31
31
|
def request method, url, body = nil, headers = {}, options = {}
|
32
32
|
raise AbstractMethodError
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
# Checks the response and raises an error if the status isn't success.
|
38
|
-
#
|
39
|
-
# @param [Integer] code the HTTP status code
|
40
|
-
# @param [String] body the HTTP response body
|
41
|
-
# @return [void]
|
42
|
-
# @raise [Animoto::Error] if the status isn't between 200 and 299
|
43
|
-
def check_response code, body
|
44
|
-
throw(:fail, [code,body]) unless (200..299).include?(code)
|
45
|
-
end
|
33
|
+
end
|
46
34
|
end
|
47
35
|
end
|
48
36
|
end
|
@@ -8,8 +8,7 @@ module Animoto
|
|
8
8
|
def request method, url, body = nil, headers = {}, options = {}
|
9
9
|
curl = build_curl method, url, body, headers, options
|
10
10
|
perform curl, method, body
|
11
|
-
|
12
|
-
curl.body_str
|
11
|
+
[curl.response_code, curl.body_str]
|
13
12
|
end
|
14
13
|
|
15
14
|
private
|
@@ -23,10 +22,14 @@ module Animoto
|
|
23
22
|
# @return [Curl::Easy] the Easy instance
|
24
23
|
def build_curl method, url, body, headers, options
|
25
24
|
::Curl::Easy.new(url) do |c|
|
25
|
+
c.http_auth_types = Curl::CURLAUTH_BASIC
|
26
26
|
c.username = options[:username]
|
27
27
|
c.password = options[:password]
|
28
28
|
c.timeout = options[:timeout]
|
29
29
|
c.post_body = body
|
30
|
+
c.ssl_verify_host = false
|
31
|
+
c.ssl_verify_peer = false
|
32
|
+
c.proxy_url = options[:proxy]
|
30
33
|
headers.each { |header, value| c.headers[header] = value }
|
31
34
|
end
|
32
35
|
end
|
@@ -39,10 +42,16 @@ module Animoto
|
|
39
42
|
# @return [void]
|
40
43
|
def perform curl, method, body
|
41
44
|
case method
|
45
|
+
when :head
|
46
|
+
curl.http_head
|
42
47
|
when :get
|
43
48
|
curl.http_get
|
44
49
|
when :post
|
45
50
|
curl.http_post(body)
|
51
|
+
when :put
|
52
|
+
curl.http_put(body)
|
53
|
+
when :delete
|
54
|
+
curl.http_delete
|
46
55
|
end
|
47
56
|
end
|
48
57
|
end
|
@@ -7,18 +7,20 @@ module Animoto
|
|
7
7
|
|
8
8
|
# A map of HTTP verb symbols to the Net::HTTP classes that handle them.
|
9
9
|
HTTP_METHOD_MAP = {
|
10
|
-
:
|
11
|
-
:
|
10
|
+
:head => Net::HTTP::Head,
|
11
|
+
:get => Net::HTTP::Get,
|
12
|
+
:post => Net::HTTP::Post,
|
13
|
+
:put => Net::HTTP::Put,
|
14
|
+
:delete => Net::HTTP::Delete
|
12
15
|
}
|
13
16
|
|
14
17
|
# @return [String]
|
15
18
|
def request method, url, body = nil, headers = {}, options = {}
|
16
19
|
uri = URI.parse(url)
|
17
|
-
http = build_http uri
|
20
|
+
http = build_http uri, options
|
18
21
|
req = build_request method, uri, body, headers, options
|
19
22
|
response = http.request req
|
20
|
-
|
21
|
-
response.body
|
23
|
+
[response.code.to_i, response.body]
|
22
24
|
end
|
23
25
|
|
24
26
|
private
|
@@ -27,8 +29,14 @@ module Animoto
|
|
27
29
|
#
|
28
30
|
# @param [URI] uri a URI object of the request URL
|
29
31
|
# @return [Net::HTTP] the HTTP object
|
30
|
-
def build_http uri
|
31
|
-
http =
|
32
|
+
def build_http uri, options
|
33
|
+
http = if options[:proxy]
|
34
|
+
proxy_uri = URI.parse(options[:proxy])
|
35
|
+
Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port).new uri.host, uri.port
|
36
|
+
else
|
37
|
+
Net::HTTP.new uri.host, uri.port
|
38
|
+
end
|
39
|
+
http.read_timeout = options[:timeout]
|
32
40
|
http.use_ssl = true
|
33
41
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
34
42
|
http
|
@@ -8,8 +8,7 @@ module Animoto
|
|
8
8
|
def request method, url, body = nil, headers = {}, options = {}
|
9
9
|
session = build_session options
|
10
10
|
response = session.request method, url, headers, :data => body
|
11
|
-
|
12
|
-
response.body
|
11
|
+
[response.status, response.body]
|
13
12
|
end
|
14
13
|
|
15
14
|
private
|
@@ -6,6 +6,7 @@ module Animoto
|
|
6
6
|
|
7
7
|
# @return [String]
|
8
8
|
def request method, url, body = nil, headers = {}, options = {}
|
9
|
+
RestClient.proxy = options[:proxy]
|
9
10
|
response = ::RestClient::Request.execute({
|
10
11
|
:method => method,
|
11
12
|
:url => url,
|
@@ -15,8 +16,7 @@ module Animoto
|
|
15
16
|
:password => options[:password],
|
16
17
|
:timeout => options[:timeout]
|
17
18
|
})
|
18
|
-
|
19
|
-
response.body
|
19
|
+
[response.code, response.body]
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -12,10 +12,11 @@ module Animoto
|
|
12
12
|
:headers => headers,
|
13
13
|
:timeout => options[:timeout],
|
14
14
|
:username => options[:username],
|
15
|
-
:password => options[:password]
|
15
|
+
:password => options[:password],
|
16
|
+
:disable_ssl_peer_verification => true,
|
17
|
+
:proxy => options[:proxy]
|
16
18
|
})
|
17
|
-
|
18
|
-
response.body
|
19
|
+
[response.code, response.body]
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
@@ -4,12 +4,40 @@ module Animoto
|
|
4
4
|
# @abstract
|
5
5
|
class Base
|
6
6
|
include Support::ContentType
|
7
|
-
|
7
|
+
|
8
8
|
# @return [String]
|
9
9
|
def self.infer_content_type
|
10
10
|
super + '_manifest'
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
|
+
# Returns the Resources::Jobs::Base descendant class associated with this manifest class
|
14
|
+
# (that is, the type of job returned when a manifest of this type is posted).
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# Manifests::Directing.associated_job_class # => Resources::Jobs::Directing
|
18
|
+
# @return [Class] the associated job class
|
19
|
+
def self.associated_job_class
|
20
|
+
Resources::Jobs.const_get(self.name.split('::').last)
|
21
|
+
end
|
22
|
+
|
23
|
+
# A URL to receive a callback after directing is finished.
|
24
|
+
# @return [String]
|
25
|
+
attr_accessor :http_callback_url
|
26
|
+
|
27
|
+
# The format of the callback; either 'xml' or 'json'.
|
28
|
+
# @return [String]
|
29
|
+
attr_accessor :http_callback_format
|
30
|
+
|
31
|
+
# Creates a new manifest
|
32
|
+
#
|
33
|
+
# @param [Hash{Symbol=>Object}] options
|
34
|
+
# @option options [String] :http_callback_url a URL to receive a callback when this job is done
|
35
|
+
# @option options [String] :http_callback_format the format of the callback
|
36
|
+
def initialize options = {}
|
37
|
+
@http_callback_url = options[:http_callback_url]
|
38
|
+
@http_callback_format = options[:http_callback_format]
|
39
|
+
end
|
40
|
+
|
13
41
|
# Returns a representation of this manifest as a Hash, used to populate
|
14
42
|
# request bodies when directing, rendering, etc.
|
15
43
|
#
|
@@ -17,7 +45,29 @@ module Animoto
|
|
17
45
|
def to_hash
|
18
46
|
{}
|
19
47
|
end
|
20
|
-
|
48
|
+
|
49
|
+
# Returns the Resources::Jobs::Base descendant class associated with this manifest (that is,
|
50
|
+
# the type of job that will be returned when this manifest is posted).
|
51
|
+
#
|
52
|
+
# @return [Class] the associated job class
|
53
|
+
def associated_job_class
|
54
|
+
self.class.associated_job_class
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
# Helper method to put the standard HTTP callback information into the manifest hash
|
60
|
+
#
|
61
|
+
# @param [Hash{String=>Object}] job_hash the hash version of the 'job' portion of this manifest
|
62
|
+
# @return [void]
|
63
|
+
# @raise [ArgumentError] if a callback url is specified but not the format
|
64
|
+
def add_callback_information job_hash
|
65
|
+
if http_callback_url
|
66
|
+
raise ArgumentError, "You must specify a http_callback_format (either 'xml' or 'json')" if http_callback_format.nil?
|
67
|
+
job_hash['http_callback'] = http_callback_url
|
68
|
+
job_hash['http_callback_format'] = http_callback_format
|
69
|
+
end
|
70
|
+
end
|
21
71
|
end
|
22
72
|
end
|
23
73
|
end
|
@@ -11,14 +11,6 @@ module Animoto
|
|
11
11
|
# @return [String]
|
12
12
|
attr_accessor :pacing
|
13
13
|
|
14
|
-
# A URL to receive a callback after directing is finished.
|
15
|
-
# @return [String]
|
16
|
-
attr_accessor :http_callback_url
|
17
|
-
|
18
|
-
# The format of the callback; either 'xml' or 'json'.
|
19
|
-
# @return [String]
|
20
|
-
attr_accessor :http_callback_format
|
21
|
-
|
22
14
|
# The array of Visual objects in this manifest.
|
23
15
|
# @return [Array<Support::Visual>]
|
24
16
|
attr_reader :visuals
|
@@ -40,13 +32,12 @@ module Animoto
|
|
40
32
|
# @option options [String] :http_callback_format the format of the callback
|
41
33
|
# @return [Manifests::Directing] the manifest
|
42
34
|
def initialize options = {}
|
35
|
+
super
|
43
36
|
@title = options[:title]
|
44
37
|
@pacing = options[:pacing] || 'default'
|
45
38
|
@style = 'original'
|
46
39
|
@visuals = []
|
47
40
|
@song = nil
|
48
|
-
@http_callback_url = options[:http_callback_url]
|
49
|
-
@http_callback_format = options[:http_callback_format]
|
50
41
|
end
|
51
42
|
|
52
43
|
# Adds a TitleCard to this manifest.
|
@@ -55,7 +46,7 @@ module Animoto
|
|
55
46
|
# @return [Assets::TitleCard] the new TitleCard
|
56
47
|
# @see Animoto::Assets::TitleCard#initialize
|
57
48
|
def add_title_card *args
|
58
|
-
card = Assets::TitleCard.new
|
49
|
+
card = Assets::TitleCard.new(*args)
|
59
50
|
@visuals << card
|
60
51
|
card
|
61
52
|
end
|
@@ -66,7 +57,7 @@ module Animoto
|
|
66
57
|
# @return [Assets::Image] the new Image
|
67
58
|
# @see Animoto::Assets::Image#initialize
|
68
59
|
def add_image *args
|
69
|
-
image = Assets::Image.new
|
60
|
+
image = Assets::Image.new(*args)
|
70
61
|
@visuals << image
|
71
62
|
image
|
72
63
|
end
|
@@ -77,7 +68,7 @@ module Animoto
|
|
77
68
|
# @return [Assets::Footage] the new Footage
|
78
69
|
# @see Animoto::Assets::Footage#initialize
|
79
70
|
def add_footage *args
|
80
|
-
footage = Assets::Footage.new
|
71
|
+
footage = Assets::Footage.new(*args)
|
81
72
|
@visuals << footage
|
82
73
|
footage
|
83
74
|
end
|
@@ -89,7 +80,7 @@ module Animoto
|
|
89
80
|
# @return [Assets::Song] the new Song
|
90
81
|
# @see Animoto::Assets::Song#initialize
|
91
82
|
def add_song *args
|
92
|
-
@song = Assets::Song.new
|
83
|
+
@song = Assets::Song.new(*args)
|
93
84
|
end
|
94
85
|
|
95
86
|
# Adds a visual/song to this manifest.
|
@@ -124,11 +115,7 @@ module Animoto
|
|
124
115
|
def to_hash options = {}
|
125
116
|
hash = { 'directing_job' => { 'directing_manifest' => {} } }
|
126
117
|
job = hash['directing_job']
|
127
|
-
|
128
|
-
raise ArgumentError, "You must specify a http_callback_format (either 'xml' or 'json')" if http_callback_format.nil?
|
129
|
-
job['http_callback'] = http_callback_url
|
130
|
-
job['http_callback_format'] = http_callback_format
|
131
|
-
end
|
118
|
+
add_callback_information job
|
132
119
|
manifest = job['directing_manifest']
|
133
120
|
manifest['style'] = style
|
134
121
|
manifest['pacing'] = pacing if pacing
|
@@ -13,14 +13,6 @@ module Animoto
|
|
13
13
|
# @return [Manifests::Rendering]
|
14
14
|
attr_reader :rendering_manifest
|
15
15
|
|
16
|
-
# A URL to receive a callback after directing is finished.
|
17
|
-
# @return [String]
|
18
|
-
attr_accessor :http_callback_url
|
19
|
-
|
20
|
-
# The format of the callback; either 'xml' or 'json'.
|
21
|
-
# @return [String]
|
22
|
-
attr_accessor :http_callback_format
|
23
|
-
|
24
16
|
# Creates a new directing-and-rendering manifest.
|
25
17
|
#
|
26
18
|
# @param [Hash{Symbol=>Object}] options
|
@@ -31,12 +23,11 @@ module Animoto
|
|
31
23
|
# @option options [String] :format the format of the rendered video
|
32
24
|
# @option options [String] :http_callback_url a URL to receive a callback when this job is done
|
33
25
|
# @option options [String] :http_callback_format the format of the callback
|
34
|
-
|
26
|
+
# @return [Manifests::DirectingAndRendering] the manifest
|
27
|
+
def initialize options = {}
|
28
|
+
super
|
35
29
|
@directing_manifest = Manifests::Directing.new(options.only(:title, :pacing))
|
36
30
|
@rendering_manifest = Manifests::Rendering.new(options.only(:resolution, :framerate, :format))
|
37
|
-
|
38
|
-
@http_callback_url = options[:http_callback_url]
|
39
|
-
@http_callback_format = options[:http_callback_format]
|
40
31
|
end
|
41
32
|
|
42
33
|
# Delegates method calls to the underlying directing or rendering manifests if
|
@@ -46,9 +37,9 @@ module Animoto
|
|
46
37
|
def method_missing *args
|
47
38
|
name = args.first
|
48
39
|
if directing_manifest.respond_to?(name)
|
49
|
-
directing_manifest.__send__
|
40
|
+
directing_manifest.__send__(*args)
|
50
41
|
elsif rendering_manifest.respond_to?(name)
|
51
|
-
rendering_manifest.__send__
|
42
|
+
rendering_manifest.__send__(*args)
|
52
43
|
else
|
53
44
|
super
|
54
45
|
end
|
@@ -63,11 +54,7 @@ module Animoto
|
|
63
54
|
def to_hash options = {}
|
64
55
|
hash = { 'directing_and_rendering_job' => {} }
|
65
56
|
job = hash['directing_and_rendering_job']
|
66
|
-
|
67
|
-
raise ArgumentError, "You must specify a http_callback_format (either 'xml' or 'json')" if http_callback_format.nil?
|
68
|
-
job['http_callback'] = http_callback_url
|
69
|
-
job['http_callback_format'] = http_callback_format
|
70
|
-
end
|
57
|
+
add_callback_information job
|
71
58
|
job['directing_manifest'] = self.directing_manifest.to_hash['directing_job']['directing_manifest']
|
72
59
|
job['rendering_manifest'] = self.rendering_manifest.to_hash['rendering_job']['rendering_manifest']
|
73
60
|
hash
|