encoding-dot-com 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ *~
7
+ \#*
8
+ .\#*
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Enrich Social Productions Ltd.
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.rdoc ADDED
@@ -0,0 +1,56 @@
1
+ = encoding-dot-com
2
+
3
+ A client library for the encoding.com[http://www.encoding.com] API.
4
+
5
+ Supports all the actions of the encoding.com API. Example usage:
6
+
7
+ require "encoding_dot_com"
8
+
9
+ # Create an interface to the encoding.com queue with your user id and secret
10
+ queue = EncodingDotCom::Queue.new(1234, "secret")
11
+
12
+ # Create one or more output formats
13
+ format = EncodingDotCom::Format.create("output" => "flv")
14
+
15
+ # Get an media item processed. You can pass multiple output formats in a hash.
16
+ media_id = queue.add_and_process("http://source/url/here", "http://destination/url/here" => format)
17
+
18
+ queue.status(media_id) # => returns a string like "Waiting for encoder" or "Finished"
19
+ queue.info(media_id) # => returns information about an item in the queue
20
+
21
+ See the API documentation for more details - Queue is a good starting place.
22
+
23
+ By default the library uses Curb for http - there is also a Net/HTTP
24
+ adapter and it is easy to write your own.
25
+
26
+ == Dependencies
27
+
28
+ * Nokogiri
29
+ * (Optionally) curb
30
+
31
+ == TODOs
32
+
33
+ * Flesh out validations to ensure that bad data does not get submitted to
34
+ encoding.com
35
+ * Full status method
36
+
37
+ == Note on Patches/Pull Requests
38
+
39
+ * Fork the project.
40
+ * Make your feature addition or bug fix.
41
+ * Add tests for it. This is important so I don't break it in a
42
+ future version unintentionally.
43
+ * Commit, do not mess with rakefile, version, or history.
44
+ (if you want to have your own version, that is fine but
45
+ bump version in a commit by itself I can ignore when I pull)
46
+ * Send me a pull request. Bonus points for topic branches.
47
+
48
+ == Authors
49
+
50
+ * {Roland Swingler}[http://github.com/knaveofdiamonds]
51
+ * {Alan Kennedy}[http://github.com/alan]
52
+ * {Levent Ali}[http://github.com/levent]
53
+
54
+ == Copyright
55
+
56
+ Copyright (c) 2009 Enrich Social Productions Ltd. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,75 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "encoding-dot-com"
8
+ gem.summary = %Q{A ruby wrapper for the encoding.com API}
9
+ gem.description = %Q{A ruby wrapper for the encoding.com API}
10
+ gem.email = "roland.swingler@gmail.com"
11
+ gem.homepage = "http://encodingdotcom.rubyforge.org/"
12
+ gem.authors = ["Roland Swingler", "Alan Kennedy", "Levent Ali"]
13
+ gem.add_dependency "nokogiri"
14
+ gem.add_development_dependency "rspec"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :spec => :check_dependencies
34
+
35
+ begin
36
+ require 'reek/rake_task'
37
+ Reek::RakeTask.new do |t|
38
+ t.fail_on_error = true
39
+ t.verbose = false
40
+ t.source_files = 'lib/**/*.rb'
41
+ end
42
+ rescue LoadError
43
+ task :reek do
44
+ abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
45
+ end
46
+ end
47
+
48
+ begin
49
+ require 'roodi'
50
+ require 'roodi_task'
51
+ RoodiTask.new do |t|
52
+ t.verbose = false
53
+ end
54
+ rescue LoadError
55
+ task :roodi do
56
+ abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
57
+ end
58
+ end
59
+
60
+ require 'rake/rdoctask'
61
+ Rake::RDocTask.new do |rdoc|
62
+ if File.exist?('VERSION')
63
+ version = File.read('VERSION')
64
+ else
65
+ version = ""
66
+ end
67
+
68
+ rdoc.rdoc_dir = 'rdoc'
69
+ rdoc.title = "Encoding dot com #{version}"
70
+ rdoc.rdoc_files.include('README*')
71
+ rdoc.rdoc_files.include('lib/**/*.rb')
72
+ end
73
+
74
+ task :default => [:spec, :roodi]
75
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,80 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{encoding-dot-com}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Roland Swingler", "Alan Kennedy", "Levent Ali"]
12
+ s.date = %q{2009-12-07}
13
+ s.description = %q{A ruby wrapper for the encoding.com API}
14
+ s.email = %q{roland.swingler@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "encoding-dot-com.gemspec",
27
+ "lib/encoding-dot-com.rb",
28
+ "lib/encoding_dot_com.rb",
29
+ "lib/encoding_dot_com/attribute_restrictions.rb",
30
+ "lib/encoding_dot_com/errors.rb",
31
+ "lib/encoding_dot_com/flv_vp6_format.rb",
32
+ "lib/encoding_dot_com/format.rb",
33
+ "lib/encoding_dot_com/http_adapters/curb_adapter.rb",
34
+ "lib/encoding_dot_com/http_adapters/net_http_adapter.rb",
35
+ "lib/encoding_dot_com/media_info.rb",
36
+ "lib/encoding_dot_com/media_list_item.rb",
37
+ "lib/encoding_dot_com/queue.rb",
38
+ "lib/encoding_dot_com/thumbnail_format.rb",
39
+ "lib/encoding_dot_com/video_format.rb",
40
+ "spec/encoding_dot_com/http_adapters/curb_adapter_spec.rb",
41
+ "spec/encoding_dot_com/http_adapters/net_http_adapter_spec.rb",
42
+ "spec/flv_vp6_format_spec.rb",
43
+ "spec/format_spec.rb",
44
+ "spec/media_list_item_spec.rb",
45
+ "spec/queue_spec.rb",
46
+ "spec/spec_helper.rb",
47
+ "spec/thumbnail_format_spec.rb"
48
+ ]
49
+ s.homepage = %q{http://encodingdotcom.rubyforge.org/}
50
+ s.rdoc_options = ["--charset=UTF-8"]
51
+ s.require_paths = ["lib"]
52
+ s.rubygems_version = %q{1.3.5}
53
+ s.summary = %q{A ruby wrapper for the encoding.com API}
54
+ s.test_files = [
55
+ "spec/flv_vp6_format_spec.rb",
56
+ "spec/spec_helper.rb",
57
+ "spec/encoding_dot_com/http_adapters/net_http_adapter_spec.rb",
58
+ "spec/encoding_dot_com/http_adapters/curb_adapter_spec.rb",
59
+ "spec/format_spec.rb",
60
+ "spec/queue_spec.rb",
61
+ "spec/media_list_item_spec.rb",
62
+ "spec/thumbnail_format_spec.rb"
63
+ ]
64
+
65
+ if s.respond_to? :specification_version then
66
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
67
+ s.specification_version = 3
68
+
69
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
70
+ s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
71
+ s.add_development_dependency(%q<rspec>, [">= 0"])
72
+ else
73
+ s.add_dependency(%q<nokogiri>, [">= 0"])
74
+ s.add_dependency(%q<rspec>, [">= 0"])
75
+ end
76
+ else
77
+ s.add_dependency(%q<nokogiri>, [">= 0"])
78
+ s.add_dependency(%q<rspec>, [">= 0"])
79
+ end
80
+ end
@@ -0,0 +1,12 @@
1
+ require 'encoding_dot_com/errors'
2
+ require 'encoding_dot_com/queue'
3
+ require 'encoding_dot_com/attribute_restrictions'
4
+ require 'encoding_dot_com/format'
5
+ require 'encoding_dot_com/video_format'
6
+ require 'encoding_dot_com/thumbnail_format'
7
+ require 'encoding_dot_com/flv_vp6_format'
8
+ require 'encoding_dot_com/media_list_item'
9
+ require 'encoding_dot_com/media_info'
10
+ require 'encoding_dot_com/http_adapters/curb_adapter'
11
+ require 'encoding_dot_com/http_adapters/net_http_adapter'
12
+
@@ -0,0 +1,74 @@
1
+ module EncodingDotCom
2
+ module AttributeRestrictionsZune #:nodoc:
3
+ def validate_size
4
+ allowed_sizes = %w{320x120 320x180 320x0 0x120 0x180}
5
+ unless size.nil? || allowed_sizes.include?(size)
6
+ raise IllegalFormatAttribute.new("Size can only be one of #{allowed_sizes.join(',')} but was #{size}")
7
+ end
8
+ end
9
+ end
10
+
11
+ module AttributeRestrictionsIpod #:nodoc:
12
+ def validate_size
13
+ allowed_sizes = %w{320x240 640x480}
14
+ unless size.nil? || allowed_sizes.include?(size)
15
+ raise IllegalFormatAttribute.new("Size can only be one of #{allowed_sizes.join(',')} but was #{size}")
16
+ end
17
+ end
18
+ end
19
+
20
+ module AttributeRestrictionsFlv #:nodoc:
21
+ # validate_inclusion_of :audio_bitrate, %w{32k 40k 48k 56k 64k 80k 96k 112k 128k 144k 160k 192k 224k 256k 320k}
22
+ # validate_inclusion_of :video_codec, %w{flv libx264 vp6}
23
+
24
+ def validate_audio_bitrate
25
+ allowed_bitrates = %w{32k 40k 48k 56k 64k 80k 96k 112k 128k 144k 160k 192k 224k 256k 320k}
26
+ end
27
+
28
+ def validate_video_codec
29
+ allowed_codecs = %w{flv libx264 vp6}
30
+ unless video_codec.nil? || allowed_codecs.include?(video_codec)
31
+ raise IllegalFormatAttribute.new("Video codec can only be one of #{allowed_codecs.join(',')} but was #{video_codec}")
32
+ end
33
+ end
34
+ end
35
+
36
+ module AttributeRestrictionsMp4 #:nodoc:
37
+ def validate_video_codec
38
+ allowed_codecs = %w{mpeg4 libx264}
39
+ unless video_codec.nil? || allowed_codecs.include?(video_codec)
40
+ raise IllegalFormatAttribute.new("Video codec can only be one of #{allowed_codecs.join(',')} but was #{video_codec}")
41
+ end
42
+ end
43
+ end
44
+
45
+ module AttributeRestrictionsFl9 #:nodoc:
46
+ end
47
+
48
+ module AttributeRestrictionsWmv #:nodoc:
49
+ end
50
+
51
+ module AttributeRestrictions3gp #:nodoc:
52
+ end
53
+
54
+ module AttributeRestrictionsM4v #:nodoc:
55
+ end
56
+
57
+ module AttributeRestrictionsIphone #:nodoc:
58
+ end
59
+
60
+ module AttributeRestrictionsAppletv #:nodoc:
61
+ end
62
+
63
+ module AttributeRestrictionsPsp #:nodoc:
64
+ end
65
+
66
+ module AttributeRestrictionsMp3 #:nodoc:
67
+ end
68
+
69
+ module AttributeRestrictionsWma #:nodoc:
70
+ end
71
+
72
+ module AttributeRestrictionsThumbnail #:nodoc:
73
+ end
74
+ end
@@ -0,0 +1,15 @@
1
+ module EncodingDotCom
2
+ # Error raised if there is an http-level problem accessing the
3
+ # encoding.com API.
4
+ class AvailabilityError < StandardError
5
+ end
6
+
7
+ # Error raised if there is an problem with the message sent to
8
+ # encoding.com API.
9
+ class MessageError < StandardError
10
+ end
11
+
12
+ # Error raised if a format's attribute has an illegal value
13
+ class IllegalFormatAttribute < StandardError
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ module EncodingDotCom
2
+ # FLV Format that uses the VP6 codec - there are fewer attributes
3
+ # that can be set for VP6 compared to other video codecs.
4
+ class FLVVP6Format < Format #:nodoc:
5
+ allowed_attributes :output, :video_codec, :size, :destination, :bitrate, :audio_bitrate, :audio_sample_rate, :audio_channels_number, :framerate
6
+
7
+ def initialize(attributes={})
8
+ @attributes = attributes.merge("output" => "flv", "video_codec" => "vp6")
9
+ validate_attributes
10
+ end
11
+
12
+ def validate_attributes
13
+ validate_size
14
+ end
15
+
16
+ private
17
+
18
+ def validate_size
19
+ return if size.nil?
20
+ if video_codec == "vp6" && ! size.split("x").all? {|n| (n.to_i % 16) == 0 }
21
+ raise IllegalFormatAttribute.new("Dimensions #{} should be multiples of 16")
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,73 @@
1
+ module EncodingDotCom
2
+ # Base class for all formats sent to encoding.com
3
+ #
4
+ # You should create formats by calling +create+ with format attributes.
5
+ class Format
6
+ class << self
7
+ # Factory method that returns an appropriate Format. The
8
+ # +output+ attribute is required, others are optional (see the
9
+ # encoding.com documentation for full list of attributes).
10
+ def create(attributes)
11
+ if attributes["output"] == "thumbnail"
12
+ ThumbnailFormat.new(attributes)
13
+ elsif attributes["output"] == "flv" && attributes["video_codec"] == "vp6"
14
+ FLVVP6Format.new(attributes)
15
+ else
16
+ VideoFormat.new(attributes)
17
+ end
18
+ end
19
+
20
+ def allowed_attributes(*attrs) #:nodoc:
21
+ @allowed_attributes ||= []
22
+ if attrs.empty?
23
+ @allowed_attributes
24
+ else
25
+ @allowed_attributes += attrs.map {|a| a.to_s }.each { |attr| define_method(attr) { @attributes[attr] } }
26
+ end
27
+ end
28
+
29
+ def boolean_attributes(*attrs) #:nodoc:
30
+ @boolean_attributes ||= []
31
+ if attrs.empty?
32
+ @boolean_attributes
33
+ else
34
+ allowed_attributes *attrs
35
+ @boolean_attributes += attrs.map {|a| a.to_s }
36
+ end
37
+ end
38
+ end
39
+
40
+ # Builds the XML for this format.
41
+ #
42
+ # +builder+:: a Nokogiri builder, declared with a block
43
+ # +destination_url+:: where the encoded file should be placed. See
44
+ # the encoding.com documentation for details.
45
+ def build_xml(builder, destination_url=nil)
46
+ logo_attributes, other_attributes = self.class.allowed_attributes.partition {|a| a[0..3] == "logo" }
47
+
48
+ builder.format {
49
+ builder.destination destination_url
50
+ other_attributes.each do |attr|
51
+ builder.send(attr, output_value(attr)) unless @attributes[attr].nil?
52
+ end
53
+ if logo_attributes.any? {|attr| @attributes[attr] }
54
+ builder.logo {
55
+ logo_attributes.each {|attr| builder.send(attr, output_value(attr)) if @attributes[attr] }
56
+ }
57
+ end
58
+ }
59
+ end
60
+
61
+ private
62
+
63
+ # Returns a value suitable for the format XML - i.e. translates
64
+ # booleans to yes/no.
65
+ def output_value(key)
66
+ if self.class.boolean_attributes.include?(key)
67
+ (@attributes[key] ? "yes" : "no")
68
+ else
69
+ @attributes[key]
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,27 @@
1
+ module EncodingDotCom
2
+ module HttpAdapters
3
+
4
+ Response = Struct.new(:code, :body)
5
+
6
+ # Wraps the curb[http://curb.rubyforge.org/] library for use with
7
+ # the Queue.
8
+ class CurbAdapter
9
+ def initialize
10
+ require 'curb'
11
+ end
12
+
13
+ # Makes a POST request. Raises an AvailabilityError if the
14
+ # request times out or has other problems.
15
+ def post(url, parameters={})
16
+ curl = Curl::Easy.new(url) {|c| c.follow_location = true }
17
+ post_parameters = parameters.map {|k,v| Curl::PostField.content(k.to_s, v.to_s) }
18
+ begin
19
+ curl.http_post(*post_parameters)
20
+ rescue => e
21
+ raise AvailabilityError.new(e.message)
22
+ end
23
+ Response.new(curl.response_code.to_s, curl.body_str)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ module EncodingDotCom
2
+ module HttpAdapters
3
+
4
+ # Wraps the Net/HTTP library for use with the Queue.
5
+ class NetHttpAdapter
6
+ def initialize
7
+ require 'net/http'
8
+ end
9
+
10
+ # Makes a POST request. Raises an AvailabilityError if the
11
+ # request times out or has other problems.
12
+ def post(url, parameters={})
13
+ Net::HTTP.post_form(URI.parse(url), parameters)
14
+ rescue => e
15
+ raise AvailabilityError.new(e.message)
16
+ rescue Timeout::Error => e
17
+ raise AvailabilityError.new(e.message)
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ require 'parsedate'
2
+
3
+ module EncodingDotCom
4
+ # Represents information about a video or image in the encoding.com queue
5
+ class MediaInfo
6
+ attr_reader :bitrate, :duration, :video_codec, :video_bitrate, :frame_rate, :size, :pixel_aspect_ratio, :display_aspect_ratio, :audio_codec, :audio_sample_rate, :audio_channels
7
+
8
+ # Creates a MediaInfo object, given a <response> Nokogiri::XML::Node
9
+ #
10
+ # See the encoding.com documentation for GetMediaInfo action for more details
11
+ def initialize(node)
12
+ @bitrate = (node / "bitrate").text
13
+ @duration = (node / "duration").text.to_f
14
+ @video_codec = (node / "video_codec").text
15
+ @video_bitrate = (node / "video_bitrate").text
16
+ @frame_rate = (node / "frame_rate").text.to_f
17
+ @size = (node / "size").text
18
+ @pixel_aspect_ratio = (node / "pixel_aspect_ratio").text
19
+ @display_aspect_ratio = (node / "display_aspect_ratio").text
20
+ @audio_codec = (node / "audio_codec").text
21
+ @audio_sample_rate = (node / "audio_sample_rate").text.to_i
22
+ @audio_channels = (node / "audio_channels").text.to_i
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ require 'parsedate'
2
+
3
+ module EncodingDotCom
4
+
5
+ # Represents a video or image in the encoding.com queue
6
+ class MediaListItem
7
+ attr_reader :media_file, :media_id, :media_status, :create_date, :start_date, :finish_date
8
+
9
+ # Creates a MediaListItem, given a <media> Nokogiri::XML::Node
10
+ #
11
+ # See the encoding.com documentation for GetMediaList for more details
12
+ def initialize(node)
13
+ @media_file = (node / "mediafile").text
14
+ @media_id = (node / "mediaid").text.to_i
15
+ @media_status = (node / "mediastatus").text
16
+ @create_date = parse_time_node(node / "createdate")
17
+ @start_date = parse_time_node(node / "startdate")
18
+ @finish_date = parse_time_node(node / "finishdate")
19
+ end
20
+
21
+ private
22
+
23
+ def parse_time_node(node)
24
+ time_elements = ParseDate.parsedate(node.text)
25
+ Time.local *time_elements unless time_elements.all? {|e| e.nil? || e == 0 }
26
+ end
27
+ end
28
+ end