spob-flix_cloud-gem 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.markdown +104 -0
- data/Rakefile +59 -0
- data/VERSION.yml +4 -0
- data/lib/flix_cloud/exceptions.rb +6 -0
- data/lib/flix_cloud/extensions/hash.rb +22 -0
- data/lib/flix_cloud/file.rb +21 -0
- data/lib/flix_cloud/file_locations.rb +34 -0
- data/lib/flix_cloud/job.rb +157 -0
- data/lib/flix_cloud/notification.rb +32 -0
- data/lib/flix_cloud/parameters.rb +19 -0
- data/lib/flix_cloud/record.rb +46 -0
- data/lib/flix_cloud/response.rb +26 -0
- data/lib/flix_cloud.rb +10 -0
- data/test/flix_cloud/file_locations_test.rb +45 -0
- data/test/flix_cloud/file_test.rb +29 -0
- data/test/flix_cloud/job_test.rb +532 -0
- data/test/flix_cloud/notification_test.rb +213 -0
- data/test/flix_cloud/parameters_test.rb +20 -0
- data/test/flix_cloud/record_test.rb +50 -0
- data/test/flix_cloud/response_test.rb +56 -0
- data/test/test_helper.rb +15 -0
- metadata +111 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Zencoder
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
FlixCloud Gem
|
2
|
+
=============
|
3
|
+
|
4
|
+
The gem for interacting with the API on [FlixCloud](http://flixcloud.com).
|
5
|
+
|
6
|
+
See [http://flixcloud.com/api](http://flixcloud.com/api) for more details on the API.
|
7
|
+
|
8
|
+
Examples
|
9
|
+
========
|
10
|
+
|
11
|
+
Rails
|
12
|
+
-----
|
13
|
+
|
14
|
+
If you're using rails, you can add the following to your environment.rb:
|
15
|
+
|
16
|
+
config.gem 'flixcloud-flix_cloud-gem', :lib => 'flix_cloud', :source => 'http://gems.github.com'
|
17
|
+
config.gem 'sevenwire-http_client', :lib => 'http_client', :source => 'http://gems.github.com'
|
18
|
+
config.gem 'crack'
|
19
|
+
|
20
|
+
Then you can run:
|
21
|
+
|
22
|
+
rake gems:install
|
23
|
+
rake gems:unpack
|
24
|
+
|
25
|
+
Ruby or Other Frameworks
|
26
|
+
------------------------
|
27
|
+
|
28
|
+
Install the gems (sudo may be necessary):
|
29
|
+
|
30
|
+
gem install flixcloud-flix_cloud-gem --source http://gems.github.com
|
31
|
+
gem install sevenwire-http_client --source http://gems.github.com
|
32
|
+
gem install crack
|
33
|
+
|
34
|
+
Then in your code you can just require the FlixCloud gem:
|
35
|
+
|
36
|
+
require 'rubygems'
|
37
|
+
require 'flix_cloud'
|
38
|
+
|
39
|
+
Creating Jobs
|
40
|
+
-------------
|
41
|
+
|
42
|
+
You can create jobs using the Job class:
|
43
|
+
|
44
|
+
job = FlixCloud::Job.new(:api_key => 'your-api-key-here',
|
45
|
+
:recipe_id => 1,
|
46
|
+
:input_url => 'http://url/to/your/input/file',
|
47
|
+
:output_url => 'ftp://url/to/your/output/file',
|
48
|
+
:output_user => 'username-for-ftp-here',
|
49
|
+
:output_password => 'password-for-ftp-here',
|
50
|
+
:watermark_url => 's3://url/to/your/watermark/file')
|
51
|
+
job.valid? # true or false
|
52
|
+
job.save # true or false
|
53
|
+
job.id # returns the id of the saved job, or nil if it failed to save
|
54
|
+
job.initialized_at # returns the time the job was created, or nil if it failed to save
|
55
|
+
|
56
|
+
Job is modeled after ActiveRecord, so create, create!, save, save!, etc all work.
|
57
|
+
|
58
|
+
See [this](http://flixcloud.com/api#sending_jobs_to_flix_cloud) for more information.
|
59
|
+
|
60
|
+
Job Notifications
|
61
|
+
-----------------
|
62
|
+
|
63
|
+
When you receive a notification from FlixCloud, you can process it using the Notification class:
|
64
|
+
|
65
|
+
job = FlixCloud::Notification.new(notification_xml_or_hash)
|
66
|
+
job.successful? # true if the state is 'successful_job', false if not
|
67
|
+
job.failed? # true if the state is 'failed_job', false if not
|
68
|
+
job.cancelled? # true if the state is 'cancelled_job', false if not
|
69
|
+
job.id # the id of the job that finished
|
70
|
+
job.finished_job_at # the time the job finished at
|
71
|
+
job.initialized_job_at # the time the job was created at
|
72
|
+
job.recipe_name # the name of the recipe used to process the job
|
73
|
+
job.recipe_id # the id of the recipe used to process the job
|
74
|
+
job.state # the state of the finished job. 'successful_job', 'failed_job', or 'cancelled_job'
|
75
|
+
job.error_message # the error message given for the job if it failed to process
|
76
|
+
job.input_media_file.url # url of the input file
|
77
|
+
job.input_media_file.width # width of the input file in pixels
|
78
|
+
job.input_media_file.height # height of the input file in pixels
|
79
|
+
job.input_media_file.size # size of the input file in bytes
|
80
|
+
job.input_media_file.duration # duration of the input file in milliseconds
|
81
|
+
job.input_media_file.cost # cost of the input file in millicents (1/1000th of a cent)
|
82
|
+
job.output_media_file.url # url of the output file
|
83
|
+
job.output_media_file.width # width of the output file in pixels
|
84
|
+
job.output_media_file.height # height of the output file in pixels
|
85
|
+
job.output_media_file.size # size of the output file in bytes
|
86
|
+
job.output_media_file.duration # duration of the output file in milliseconds
|
87
|
+
job.output_media_file.cost # cost of the output file in millicents (1/1000th of a cent)
|
88
|
+
job.watermark_file.url # url of the watermark file
|
89
|
+
job.watermark_file.size # size of the watermark file in bytes
|
90
|
+
job.watermark_file.cost # cost of the watermark file in millicents (1/1000th of a cent)
|
91
|
+
|
92
|
+
See [this](http://flixcloud.com/api#job_notifications) for more information.
|
93
|
+
|
94
|
+
Note
|
95
|
+
----
|
96
|
+
|
97
|
+
Creating jobs sends HTTP requests to FlixCloud, which may take some time. It's
|
98
|
+
best to do this asynchronously in your application.
|
99
|
+
|
100
|
+
|
101
|
+
COPYRIGHT
|
102
|
+
=========
|
103
|
+
|
104
|
+
Copyright (c) 2009 Zencoder. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "flix_cloud-gem"
|
8
|
+
gem.summary = %{Gem for integrating with http://flixcloud.com}
|
9
|
+
gem.email = "nate@sevenwire.com"
|
10
|
+
gem.homepage = "http://github.com/zencoder/flix_cloud-gem"
|
11
|
+
gem.authors = ["Nathan Sutton"]
|
12
|
+
gem.add_dependency('builder', '>= 2.1.2')
|
13
|
+
gem.add_dependency('crack', '>= 0.1.1')
|
14
|
+
gem.add_dependency('sevenwire-http_client', '>= 0.1.0')
|
15
|
+
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
Rake::TestTask.new(:test) do |test|
|
24
|
+
test.libs << 'lib' << 'test'
|
25
|
+
test.pattern = 'test/**/*_test.rb'
|
26
|
+
test.verbose = true
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
require 'rcov/rcovtask'
|
31
|
+
Rcov::RcovTask.new do |test|
|
32
|
+
test.libs << 'test'
|
33
|
+
test.pattern = 'test/**/*_test.rb'
|
34
|
+
test.verbose = true
|
35
|
+
end
|
36
|
+
rescue LoadError
|
37
|
+
task :rcov do
|
38
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
if File.exist?('VERSION.yml')
|
48
|
+
config = YAML.load(File.read('VERSION.yml'))
|
49
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
50
|
+
else
|
51
|
+
version = ""
|
52
|
+
end
|
53
|
+
|
54
|
+
rdoc.rdoc_dir = 'rdoc'
|
55
|
+
rdoc.title = "flix_cloud-gem #{version}"
|
56
|
+
rdoc.rdoc_files.include('README*')
|
57
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
58
|
+
end
|
59
|
+
|
data/VERSION.yml
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
class FlixCloud::Error < StandardError; end
|
2
|
+
class FlixCloud::SaveError < FlixCloud::Error; end
|
3
|
+
class FlixCloud::CreateError < FlixCloud::Error; end
|
4
|
+
class FlixCloud::ServerBrokeConnection < FlixCloud::Error; end
|
5
|
+
class FlixCloud::RequestTimeout < FlixCloud::Error; end
|
6
|
+
class FlixCloud::ConnectionRefused < FlixCloud::Error; end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module FlixCloud
|
2
|
+
module Extensions
|
3
|
+
# Both methods ripped directly out of rails
|
4
|
+
module Hash
|
5
|
+
def deep_merge(other_hash)
|
6
|
+
self.merge(other_hash) do |key, oldval, newval|
|
7
|
+
oldval = oldval.to_hash if oldval.respond_to?(:to_hash)
|
8
|
+
newval = newval.to_hash if newval.respond_to?(:to_hash)
|
9
|
+
oldval.class.to_s == 'Hash' && newval.class.to_s == 'Hash' ? oldval.deep_merge(newval) : newval
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns a new hash with +self+ and +other_hash+ merged recursively.
|
14
|
+
# Modifies the receiver in place.
|
15
|
+
def deep_merge!(other_hash)
|
16
|
+
replace(deep_merge(other_hash))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Hash.send(:include, FlixCloud::Extensions::Hash) unless Hash.instance_methods.include?('deep_merge')
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class FlixCloud::File < FlixCloud::Record
|
2
|
+
|
3
|
+
attr_accessor :url, :size, :width, :height, :duration, :cost
|
4
|
+
|
5
|
+
record_column :parameters, 'Parameters'
|
6
|
+
|
7
|
+
def valid?
|
8
|
+
self.errors = []
|
9
|
+
|
10
|
+
unless url
|
11
|
+
self.errors << "url is required"
|
12
|
+
end
|
13
|
+
|
14
|
+
if parameters && !parameters.valid?
|
15
|
+
self.errors << {:parameters => parameters.errors}
|
16
|
+
end
|
17
|
+
|
18
|
+
errors.empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class FlixCloud::FileLocations < FlixCloud::Record
|
2
|
+
|
3
|
+
record_column :input, 'File'
|
4
|
+
record_column :output, 'File'
|
5
|
+
record_column :watermark, 'File'
|
6
|
+
record_column :thumbnails, 'File'
|
7
|
+
|
8
|
+
def valid?
|
9
|
+
self.errors = []
|
10
|
+
|
11
|
+
if input
|
12
|
+
unless input.valid?
|
13
|
+
self.errors << {:input => input.errors}
|
14
|
+
end
|
15
|
+
else
|
16
|
+
self.errors << "input is required"
|
17
|
+
end
|
18
|
+
|
19
|
+
if output
|
20
|
+
unless output.valid?
|
21
|
+
self.errors << {:output => output.errors}
|
22
|
+
end
|
23
|
+
else
|
24
|
+
self.errors << "output is required"
|
25
|
+
end
|
26
|
+
|
27
|
+
if watermark && !watermark.valid?
|
28
|
+
self.errors << {:watermark => watermark.errors}
|
29
|
+
end
|
30
|
+
|
31
|
+
errors.empty?
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
class FlixCloud::Job < FlixCloud::Record
|
2
|
+
|
3
|
+
attr_accessor :id, :initialized_at, :api_key, :recipe_id, :recipe_name, :response
|
4
|
+
|
5
|
+
record_column :file_locations, 'FileLocations'
|
6
|
+
|
7
|
+
def initialize(attrs={})
|
8
|
+
super
|
9
|
+
self.shortcut_attributes = attrs
|
10
|
+
end
|
11
|
+
|
12
|
+
def valid?
|
13
|
+
self.errors = []
|
14
|
+
|
15
|
+
if file_locations
|
16
|
+
unless file_locations.valid?
|
17
|
+
self.errors << {:file_locations => file_locations.errors}
|
18
|
+
end
|
19
|
+
else
|
20
|
+
self.errors << "file_locations is required"
|
21
|
+
end
|
22
|
+
|
23
|
+
if recipe_id || recipe_name
|
24
|
+
if recipe_id && recipe_name
|
25
|
+
self.errors << "recipe_id and recipe_name cannot both be used"
|
26
|
+
end
|
27
|
+
else
|
28
|
+
self.errors << "recipe_id or recipe_name is required"
|
29
|
+
end
|
30
|
+
|
31
|
+
unless api_key
|
32
|
+
self.errors << "api_key is required"
|
33
|
+
end
|
34
|
+
|
35
|
+
errors.empty?
|
36
|
+
end
|
37
|
+
|
38
|
+
def save
|
39
|
+
return false unless valid?
|
40
|
+
|
41
|
+
self.response = post('jobs', to_xml)
|
42
|
+
|
43
|
+
if response.success?
|
44
|
+
self.id = response.body_as_hash['job']['id']
|
45
|
+
self.initialized_at = response.body_as_hash['job']['initialized_job_at']
|
46
|
+
else
|
47
|
+
self.errors = response.errors
|
48
|
+
end
|
49
|
+
|
50
|
+
response.success?
|
51
|
+
end
|
52
|
+
|
53
|
+
def save!
|
54
|
+
raise FlixCloud::SaveError unless save
|
55
|
+
true
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.create(attrs={})
|
59
|
+
job = new(attrs)
|
60
|
+
job.save
|
61
|
+
job
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.create!(attrs={})
|
65
|
+
job = create(attrs)
|
66
|
+
raise FlixCloud::CreateError unless job.id
|
67
|
+
job
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_xml
|
71
|
+
xml = Builder::XmlMarkup.new
|
72
|
+
|
73
|
+
xml.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
|
74
|
+
|
75
|
+
xml.tag!("api-request") do
|
76
|
+
xml.tag!("api-key", api_key)
|
77
|
+
|
78
|
+
if recipe_name
|
79
|
+
xml.tag!("recipe-name", recipe_name)
|
80
|
+
else
|
81
|
+
xml.tag!("recipe-id", recipe_id)
|
82
|
+
end
|
83
|
+
|
84
|
+
if file_locations
|
85
|
+
xml.tag!("file-locations") do
|
86
|
+
if file_locations.input
|
87
|
+
xml.input do
|
88
|
+
xml.url(file_locations.input.url)
|
89
|
+
if file_locations.input.parameters
|
90
|
+
xml.parameters do
|
91
|
+
xml.user(file_locations.input.parameters.user)
|
92
|
+
xml.password(file_locations.input.parameters.password)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
if file_locations.output
|
99
|
+
xml.output do
|
100
|
+
xml.url(file_locations.output.url)
|
101
|
+
if file_locations.output.parameters
|
102
|
+
xml.parameters do
|
103
|
+
xml.user(file_locations.output.parameters.user)
|
104
|
+
xml.password(file_locations.output.parameters.password)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
if file_locations.watermark
|
111
|
+
xml.watermark do
|
112
|
+
xml.url(file_locations.watermark.url)
|
113
|
+
if file_locations.watermark.parameters
|
114
|
+
xml.parameters do
|
115
|
+
xml.user(file_locations.watermark.parameters.user)
|
116
|
+
xml.password(file_locations.watermark.parameters.password)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
if file_locations.thumbnails
|
123
|
+
xml.thumbnails do
|
124
|
+
xml.url(file_locations.thumbnails.url)
|
125
|
+
xml.prefix "thumb_"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
xml.target!
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
protected
|
137
|
+
|
138
|
+
def shortcut_attributes=(attrs)
|
139
|
+
translated_attributes = {}
|
140
|
+
|
141
|
+
attrs.each do |key, value|
|
142
|
+
if match = key.to_s.match(/^(input|output|watermark|thumbnails)_(url|user|password)$/)
|
143
|
+
file_type = match[1].to_sym
|
144
|
+
parameter_type = match[2].to_sym
|
145
|
+
|
146
|
+
if parameter_type == :url
|
147
|
+
translated_attributes.deep_merge!(:file_locations => { file_type => { :url => value}})
|
148
|
+
else
|
149
|
+
translated_attributes.deep_merge!(:file_locations => { file_type => { :parameters => { parameter_type => value}}})
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
self.attributes = translated_attributes unless translated_attributes.empty?
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class FlixCloud::Notification < FlixCloud::Record
|
2
|
+
attr_accessor :xml, :id, :finished_job_at, :initialized_job_at,
|
3
|
+
:recipe_name, :recipe_id, :state, :error_message
|
4
|
+
|
5
|
+
record_column :input_media_file, 'File'
|
6
|
+
record_column :output_media_file, 'File'
|
7
|
+
record_column :watermark_file, 'File'
|
8
|
+
|
9
|
+
def initialize(attrs={})
|
10
|
+
if attrs.is_a?(String)
|
11
|
+
self.xml = attrs
|
12
|
+
attrs = Crack::XML.parse(attrs)
|
13
|
+
end
|
14
|
+
|
15
|
+
attrs = attrs['job'] if attrs['job']
|
16
|
+
|
17
|
+
super(attrs)
|
18
|
+
end
|
19
|
+
|
20
|
+
def successful?
|
21
|
+
state == 'successful_job'
|
22
|
+
end
|
23
|
+
|
24
|
+
def failed?
|
25
|
+
state == 'failed_job'
|
26
|
+
end
|
27
|
+
|
28
|
+
def cancelled?
|
29
|
+
state == 'cancelled_job'
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class FlixCloud::Parameters < FlixCloud::File
|
2
|
+
|
3
|
+
attr_accessor :user, :password
|
4
|
+
|
5
|
+
def valid?
|
6
|
+
self.errors = []
|
7
|
+
|
8
|
+
unless user
|
9
|
+
self.errors << "user is required"
|
10
|
+
end
|
11
|
+
|
12
|
+
unless password
|
13
|
+
self.errors << "password is required"
|
14
|
+
end
|
15
|
+
|
16
|
+
errors.empty?
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class FlixCloud::Record
|
2
|
+
|
3
|
+
attr_accessor :errors
|
4
|
+
|
5
|
+
def initialize(attrs={})
|
6
|
+
self.errors = []
|
7
|
+
self.attributes = attrs
|
8
|
+
end
|
9
|
+
|
10
|
+
def attributes=(attrs)
|
11
|
+
attrs.each do |key, value|
|
12
|
+
send("#{key}=", value) if respond_to?("#{key}=")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.record_column(attribute, klass)
|
17
|
+
eval %{
|
18
|
+
attr_reader :#{attribute}
|
19
|
+
|
20
|
+
def #{attribute}=(value)
|
21
|
+
if @#{attribute}
|
22
|
+
@#{attribute}.attributes = value
|
23
|
+
else
|
24
|
+
@#{attribute} = FlixCloud::#{klass}.new(value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def post(path, body)
|
34
|
+
begin
|
35
|
+
FlixCloud::Response.new(HttpClient::Resource.new("https://flixcloud.com/#{path}",
|
36
|
+
:verify_ssl => OpenSSL::SSL::VERIFY_PEER).post(body, :content_type => 'application/xml', :accept => 'application/xml'))
|
37
|
+
rescue HttpClient::ServerBrokeConnection
|
38
|
+
raise FlixCloud::ServerBrokeConnection, $!.message
|
39
|
+
rescue HttpClient::RequestTimeout
|
40
|
+
raise FlixCloud::RequestTimeout, $!.message
|
41
|
+
rescue HttpClient::ConnectionRefused
|
42
|
+
raise FlixCloud::ConnectionRefused, $!.message
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class FlixCloud::Response
|
2
|
+
|
3
|
+
attr_accessor :code, :body, :errors, :body_as_hash
|
4
|
+
|
5
|
+
def initialize(response)
|
6
|
+
self.code = response.code
|
7
|
+
self.body = response.to_s
|
8
|
+
self.body_as_hash = Crack::XML.parse(response.to_s)
|
9
|
+
self.errors = []
|
10
|
+
process_response_xml
|
11
|
+
end
|
12
|
+
|
13
|
+
def success?
|
14
|
+
201 == code.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def process_response_xml
|
21
|
+
if body_as_hash['errors'] && body_as_hash['errors'].is_a?(Hash) && body_as_hash['errors']['error']
|
22
|
+
self.errors = Array(body_as_hash['errors']['error'])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/flix_cloud.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'builder'
|
2
|
+
require 'http_client'
|
3
|
+
require 'crack/xml'
|
4
|
+
|
5
|
+
module FlixCloud; end
|
6
|
+
|
7
|
+
%w(record job file_locations file parameters response extensions/hash
|
8
|
+
exceptions notification).each do |file|
|
9
|
+
require File.dirname(__FILE__) + "/flix_cloud/#{file}"
|
10
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FlixCloud::FileLocationsTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "When validationg a file locations object with no attributes set" do
|
6
|
+
setup do
|
7
|
+
@file_locations = FlixCloud::FileLocations.new
|
8
|
+
@file_locations.valid?
|
9
|
+
end
|
10
|
+
|
11
|
+
should "require input" do
|
12
|
+
assert_match /input is required/, @file_locations.errors.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
should "require output" do
|
16
|
+
assert_match /output is required/, @file_locations.errors.to_s
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "When validating a file locations object with input, output, and watermark objects that are invalid" do
|
21
|
+
setup do
|
22
|
+
@file_locations = FlixCloud::FileLocations.new(:input => {}, :output => {}, :watermark => {})
|
23
|
+
@file_locations.valid?
|
24
|
+
end
|
25
|
+
|
26
|
+
should "inherit the input object's errors" do
|
27
|
+
assert @file_locations.errors.any?{|error|
|
28
|
+
error.is_a?(Hash) && error[:input] && !error[:input].empty?
|
29
|
+
}, "Did not inherit input object's errors"
|
30
|
+
end
|
31
|
+
|
32
|
+
should "inherit the output object's errors" do
|
33
|
+
assert @file_locations.errors.any?{|error|
|
34
|
+
error.is_a?(Hash) && error[:output] && !error[:output].empty?
|
35
|
+
}, "Did not inherit output object's errors"
|
36
|
+
end
|
37
|
+
|
38
|
+
should "inherit the watermark object's errors" do
|
39
|
+
assert @file_locations.errors.any?{|error|
|
40
|
+
error.is_a?(Hash) && error[:watermark] && !error[:watermark].empty?
|
41
|
+
}, "Did not inherit watermark object's errors"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FlixCloud::FileTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "When validating a file object with no attributes set" do
|
6
|
+
setup do
|
7
|
+
@file = FlixCloud::File.new
|
8
|
+
@file.valid?
|
9
|
+
end
|
10
|
+
|
11
|
+
should "require url" do
|
12
|
+
assert_match /url is required/, @file.errors.to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "When validating a file object with a parameters object that is invalid" do
|
17
|
+
setup do
|
18
|
+
@file = FlixCloud::File.new(:parameters => {})
|
19
|
+
@file.valid?
|
20
|
+
end
|
21
|
+
|
22
|
+
should "inherit the parameters object's errors" do
|
23
|
+
assert @file.errors.any?{|error|
|
24
|
+
error.is_a?(Hash) && error[:parameters] && !error[:parameters].empty?
|
25
|
+
}, "Did not inherit parameters object's errors"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|