cannikin-encosion 0.1.4
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 +5 -0
- data/.gitignore +3 -0
- data/LICENSE +20 -0
- data/README.rdoc +67 -0
- data/Rakefile +58 -0
- data/VERSION +1 -0
- data/encosion.gemspec +60 -0
- data/lib/encosion/base.rb +181 -0
- data/lib/encosion/cue_point.rb +0 -0
- data/lib/encosion/exceptions.rb +4 -0
- data/lib/encosion/image.rb +0 -0
- data/lib/encosion/playlist.rb +24 -0
- data/lib/encosion/rendition.rb +0 -0
- data/lib/encosion/video.rb +238 -0
- data/lib/encosion.rb +54 -0
- data/test/encosion_test.rb +7 -0
- data/test/movie.mov +0 -0
- data/test/test_helper.rb +10 -0
- metadata +91 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Rob Cameron
|
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,67 @@
|
|
1
|
+
Encosion (en-co-shen) is a Ruby library for working with Brightcove's Media API.
|
2
|
+
|
3
|
+
= Installation
|
4
|
+
|
5
|
+
To get the gem:
|
6
|
+
gem sources -a http://gems.github.com
|
7
|
+
sudo gem install cannikin-encosion
|
8
|
+
|
9
|
+
= Usage
|
10
|
+
|
11
|
+
Encosion has several class methods that are similar to those found in ActiveRecord
|
12
|
+
for finding records. You'll pass a hash of options which correspond to those expected
|
13
|
+
by Brightcove (see http://docs.brightcove.com/en/media/). All calls will require you
|
14
|
+
to include either your read or write token depending on whether you are using the
|
15
|
+
read or write methods.
|
16
|
+
|
17
|
+
== Read Methods
|
18
|
+
|
19
|
+
require 'rubygems'
|
20
|
+
require 'encosion'
|
21
|
+
|
22
|
+
# find all videos, 25 at a time, and return the first page
|
23
|
+
videos = Encosion::Video.find(:all, :token => '123abc', :page_size => 25, :page_number => 1)
|
24
|
+
|
25
|
+
# find a single video by Brightcove video id
|
26
|
+
video = Encosion::Video.find(12345, :token => '123abc')
|
27
|
+
|
28
|
+
# find several videos by their Brightcove video ids
|
29
|
+
videos = Encosion::Video.find(12345, 67890, 24680, :token => '123abc')
|
30
|
+
|
31
|
+
# find videos by your own reference id
|
32
|
+
video = Encosion::Video.find_by_reference_id('our_internal_id', :token => '123abc')
|
33
|
+
|
34
|
+
See Encosion::Video for all the available find methods and their variants.
|
35
|
+
|
36
|
+
== Write Methods
|
37
|
+
|
38
|
+
To write a video to Brightcove you will instantiate Encosion::Video, set a few required fields
|
39
|
+
and then save it:
|
40
|
+
|
41
|
+
require 'rubygems'
|
42
|
+
require 'encosion'
|
43
|
+
|
44
|
+
new_video = Encosion::Video.new(:file => File.new('/path/to/file'), :name => "My Awesome Video", :short_description => "A video of some awesome happenings", :tags => ['awesome','sweet'])
|
45
|
+
brightcove_id = new_video.save(:token => '123abc')
|
46
|
+
|
47
|
+
The save() method returns Brightcove's ID for the video (assuming the save was successful).
|
48
|
+
|
49
|
+
Brightcove requires a name and short description before it will let you save a video. The fields
|
50
|
+
that you can set are those that Brightcove considers writable:
|
51
|
+
|
52
|
+
* name (string)
|
53
|
+
* short_description (string)
|
54
|
+
* long_description (string)
|
55
|
+
* link_url (string)
|
56
|
+
* link_text (string)
|
57
|
+
* tags (array of strings)
|
58
|
+
* reference_id (string)
|
59
|
+
* economics (enumerable, either :free or :ad_supported)
|
60
|
+
|
61
|
+
And of course the video file itself.
|
62
|
+
|
63
|
+
= To Do
|
64
|
+
|
65
|
+
* Implement the remaining Video write methods: update_video, delete_video, share_video, get_upload_status, add_image
|
66
|
+
* Implement the Playlist API read/write methods
|
67
|
+
* Create a persistent config store so you can set the tokens once instead of on each method call
|
data/Rakefile
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "encosion"
|
8
|
+
gem.summary = %q{Ruby library for working with the Brightcove API}
|
9
|
+
gem.email = "cannikinn@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/cannikin/encosion"
|
11
|
+
gem.authors = ["Rob Cameron"]
|
12
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
|
+
gem.add_dependency('httpclient', '>= 2.1.5.2')
|
14
|
+
gem.add_dependency('json', '>= 1.1.7')
|
15
|
+
end
|
16
|
+
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/*_test.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/*_test.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
task :default => :test
|
43
|
+
|
44
|
+
require 'rake/rdoctask'
|
45
|
+
Rake::RDocTask.new do |rdoc|
|
46
|
+
if File.exist?('VERSION.yml')
|
47
|
+
config = YAML.load(File.read('VERSION.yml'))
|
48
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
49
|
+
else
|
50
|
+
version = ""
|
51
|
+
end
|
52
|
+
|
53
|
+
rdoc.rdoc_dir = 'rdoc'
|
54
|
+
rdoc.title = "encosion #{version}"
|
55
|
+
rdoc.rdoc_files.include('README*')
|
56
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
57
|
+
end
|
58
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.4
|
data/encosion.gemspec
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{encosion}
|
5
|
+
s.version = "0.1.4"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Rob Cameron"]
|
9
|
+
s.date = %q{2009-07-07}
|
10
|
+
s.email = %q{cannikinn@gmail.com}
|
11
|
+
s.extra_rdoc_files = [
|
12
|
+
"LICENSE",
|
13
|
+
"README.rdoc"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".document",
|
17
|
+
".gitignore",
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"encosion.gemspec",
|
23
|
+
"lib/encosion.rb",
|
24
|
+
"lib/encosion/base.rb",
|
25
|
+
"lib/encosion/cue_point.rb",
|
26
|
+
"lib/encosion/exceptions.rb",
|
27
|
+
"lib/encosion/image.rb",
|
28
|
+
"lib/encosion/playlist.rb",
|
29
|
+
"lib/encosion/rendition.rb",
|
30
|
+
"lib/encosion/video.rb",
|
31
|
+
"test/encosion_test.rb",
|
32
|
+
"test/movie.mov",
|
33
|
+
"test/test_helper.rb"
|
34
|
+
]
|
35
|
+
s.homepage = %q{http://github.com/cannikin/encosion}
|
36
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
37
|
+
s.require_paths = ["lib"]
|
38
|
+
s.rubygems_version = %q{1.3.4}
|
39
|
+
s.summary = %q{Ruby library for working with the Brightcove API}
|
40
|
+
s.test_files = [
|
41
|
+
"test/encosion_test.rb",
|
42
|
+
"test/test_helper.rb"
|
43
|
+
]
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
47
|
+
s.specification_version = 3
|
48
|
+
|
49
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
50
|
+
s.add_runtime_dependency(%q<httpclient>, [">= 2.1.5.2"])
|
51
|
+
s.add_runtime_dependency(%q<json>, [">= 1.1.7"])
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<httpclient>, [">= 2.1.5.2"])
|
54
|
+
s.add_dependency(%q<json>, [">= 1.1.7"])
|
55
|
+
end
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<httpclient>, [">= 2.1.5.2"])
|
58
|
+
s.add_dependency(%q<json>, [">= 1.1.7"])
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'httpclient'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Encosion
|
7
|
+
|
8
|
+
# Generic Encosion error class
|
9
|
+
class EncosionError < StandardError
|
10
|
+
end
|
11
|
+
|
12
|
+
# Raised when there is no token (required to use the Brightcove API)
|
13
|
+
class MissingToken < EncosionError
|
14
|
+
end
|
15
|
+
|
16
|
+
# Raised when some parameter is missing that we need in order to do a search
|
17
|
+
class AssetNotFound < EncosionError
|
18
|
+
end
|
19
|
+
|
20
|
+
# Raised when Brightcove doesn't like the call that was made for whatever reason
|
21
|
+
class BrightcoveException < EncosionError
|
22
|
+
end
|
23
|
+
|
24
|
+
# Raised when Brightcove doesn't like the call that was made for whatever reason
|
25
|
+
class NoFile < EncosionError
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# The base for all Encosion objects
|
30
|
+
class Base
|
31
|
+
|
32
|
+
attr_accessor :read_token, :write_token
|
33
|
+
|
34
|
+
#
|
35
|
+
# Class methods
|
36
|
+
#
|
37
|
+
class << self
|
38
|
+
|
39
|
+
# Does a GET to search photos and other good stuff
|
40
|
+
def find(*args)
|
41
|
+
options = extract_options(args)
|
42
|
+
case args.first
|
43
|
+
when :all then find_all(options)
|
44
|
+
else find_from_ids(args,options)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# This is an alias for find(:all)
|
49
|
+
def all(*args)
|
50
|
+
find(:all, *args)
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
|
56
|
+
# Pulls any Hash off the end of an array of arguments and returns it
|
57
|
+
def extract_options(opts)
|
58
|
+
opts.last.is_a?(::Hash) ? opts.pop : {}
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# Find an asset from a single or array of ids
|
63
|
+
def find_from_ids(ids, options)
|
64
|
+
expects_array = ids.first.kind_of?(Array)
|
65
|
+
return ids.first if expects_array && ids.first.empty?
|
66
|
+
|
67
|
+
ids = ids.flatten.compact.uniq
|
68
|
+
|
69
|
+
case ids.size
|
70
|
+
when 0
|
71
|
+
raise AssetNotFound, "Couldn't find #{self.class} without an ID"
|
72
|
+
when 1
|
73
|
+
result = find_one(ids.first, options)
|
74
|
+
expects_array ? [ result ] : result
|
75
|
+
else
|
76
|
+
find_some(ids, options)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
# Performs an HTTP GET
|
82
|
+
def get(server,port,path,secure,command,options)
|
83
|
+
http = HTTPClient.new
|
84
|
+
url = secure ? 'https://' : 'http://'
|
85
|
+
url += "#{server}:#{port}#{path}"
|
86
|
+
|
87
|
+
options.merge!({'command' => command })
|
88
|
+
query_string = options.collect { |key,value| "#{key.to_s}=#{value.to_s}" }.join('&')
|
89
|
+
|
90
|
+
response = http.get(url, query_string)
|
91
|
+
|
92
|
+
body = response.body.content.strip == 'null' ? nil : JSON.parse(response.body.content.strip) # if the call returns 'null' then there were no valid results
|
93
|
+
header = response.header
|
94
|
+
|
95
|
+
error_check(header,body)
|
96
|
+
|
97
|
+
return body
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
# Checks the HTTP response and handles any errors
|
102
|
+
def error_check(header,body)
|
103
|
+
if header.status_code == 200
|
104
|
+
return true if body.nil?
|
105
|
+
puts body['error']
|
106
|
+
if body.has_key? 'error' && !body['error'].nil?
|
107
|
+
message = "Brightcove responded with an error: #{body['error']} (code #{body['code']})"
|
108
|
+
body['errors'].each do |error|
|
109
|
+
message += "\n#{error.values.first} (code #{error.values.last})"
|
110
|
+
end if body.has_key? 'errors'
|
111
|
+
raise BrightcoveException, message
|
112
|
+
end
|
113
|
+
else
|
114
|
+
# should only happen if the Brightcove API is unavailable (even BC errors return a 200)
|
115
|
+
raise BrightcoveException, body + " (status code: #{header.status_code})"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# Turns a hash into a query string and appends the token
|
121
|
+
def queryize_args(args, type)
|
122
|
+
case type
|
123
|
+
when :read
|
124
|
+
raise MissingToken, 'No read token found' if @read_token.nil?
|
125
|
+
args.merge!({ :token => @read_token })
|
126
|
+
when :write
|
127
|
+
raise MissingToken, 'No write token found' if @write_token.nil?
|
128
|
+
args.merge!({ :token => @write_token })
|
129
|
+
end
|
130
|
+
return args.collect { |key,value| "#{key.to_s}=#{value.to_s}" }.join('&')
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
#
|
137
|
+
# Instance methods
|
138
|
+
#
|
139
|
+
private
|
140
|
+
# Performs an HTTP POST
|
141
|
+
def post(server,port,path,secure,command,options,instance)
|
142
|
+
http = HTTPClient.new
|
143
|
+
url = secure ? 'https://' : 'http://'
|
144
|
+
url += "#{server}:#{port}#{path}"
|
145
|
+
|
146
|
+
content = { 'json' => { 'method' => command, 'params' => options }.to_json } # package up the variables as a JSON-RPC string
|
147
|
+
content.merge!({ 'file' => instance.file }) if instance.file # and add a file if there is one
|
148
|
+
|
149
|
+
response = http.post(url, content)
|
150
|
+
# get the header and body for error checking
|
151
|
+
body = JSON.parse(response.body.content.strip)
|
152
|
+
header = response.header
|
153
|
+
|
154
|
+
error_check(header,body)
|
155
|
+
# if we get here then no exceptions were raised
|
156
|
+
return body
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
# TODO: shouldn't need to duplicate this method here, some way to call the class method
|
161
|
+
# Checks the HTTP response and handles any errors
|
162
|
+
def error_check(header,body)
|
163
|
+
if header.status_code == 200
|
164
|
+
return true if body.nil?
|
165
|
+
puts body['error']
|
166
|
+
if body.has_key? 'error' && !body['error'].nil?
|
167
|
+
message = "Brightcove responded with an error: #{body['error']} (code #{body['code']})"
|
168
|
+
body['errors'].each do |error|
|
169
|
+
message += "\n#{error.values.first} (code #{error.values.last})"
|
170
|
+
end if body.has_key? 'errors'
|
171
|
+
raise BrightcoveException, message
|
172
|
+
end
|
173
|
+
else
|
174
|
+
# should only happen if the Brightcove API is unavailable (even BC errors return a 200)
|
175
|
+
raise BrightcoveException, body + " (status code: #{header.status_code})"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Encosion
|
2
|
+
|
3
|
+
class Playlist
|
4
|
+
|
5
|
+
attr_reader :id, :name, :short_description, :reference_id, :videos
|
6
|
+
|
7
|
+
def initialize(obj)
|
8
|
+
@id = obj['id']
|
9
|
+
@name = obj['name']
|
10
|
+
@short_description = obj['shortDescription']
|
11
|
+
@videos = obj['videos'].collect { |video| Video.new(video) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_json
|
15
|
+
{ :id => @id,
|
16
|
+
:name => @name,
|
17
|
+
:short_description => @short_description,
|
18
|
+
:reference_id => @reference_id,
|
19
|
+
:videos => @videos }.to_json
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
File without changes
|
@@ -0,0 +1,238 @@
|
|
1
|
+
module Encosion
|
2
|
+
|
3
|
+
class Video < Base
|
4
|
+
|
5
|
+
SERVER = 'api.brightcove.com'
|
6
|
+
PORT = 80
|
7
|
+
SECURE = false
|
8
|
+
READ_PATH = '/services/library'
|
9
|
+
WRITE_PATH = '/services/post'
|
10
|
+
ENUMS = { :economics => { :free => 'FREE', :ad_supported => 'AD_SUPPORTED'}}
|
11
|
+
|
12
|
+
attr_accessor(:name,
|
13
|
+
:short_description,
|
14
|
+
:long_description,
|
15
|
+
:link_url,
|
16
|
+
:link_text,
|
17
|
+
:tags,
|
18
|
+
:reference_id,
|
19
|
+
:economics,
|
20
|
+
:file)
|
21
|
+
attr_reader(:id,
|
22
|
+
:account_id,
|
23
|
+
:flv_url,
|
24
|
+
:creation_date,
|
25
|
+
:published_date,
|
26
|
+
:last_modified_date,
|
27
|
+
:video_still_url,
|
28
|
+
:thumbnail_url,
|
29
|
+
:length,
|
30
|
+
:plays_total,
|
31
|
+
:plays_trailing_week)
|
32
|
+
|
33
|
+
#
|
34
|
+
# Class methods
|
35
|
+
#
|
36
|
+
class << self
|
37
|
+
|
38
|
+
# Find a video by reference_id. Invokes Brightcove Media API command 'find_video_by_reference_id' or
|
39
|
+
# 'find_videos_by_reference_ids' depending on whether you call one or multiple ids
|
40
|
+
#
|
41
|
+
# Encosion::Video.find_by_reference_id('mycompany_1',:token => 'asdf')
|
42
|
+
# Encosion::Video.find_by_reference_id('mycompany_1','mycompany_2','mycompany_3',:token => 'asdf')
|
43
|
+
|
44
|
+
def find_by_reference_id(*args)
|
45
|
+
options = extract_options(args)
|
46
|
+
ids = args.flatten.compact.uniq
|
47
|
+
|
48
|
+
case ids.size
|
49
|
+
when 0
|
50
|
+
raise AssetNotFound, "Couldn't find #{self.class} without a reference ID"
|
51
|
+
when 1
|
52
|
+
options.merge!({:reference_id => ids.first})
|
53
|
+
response = get(SERVER,PORT,READ_PATH,SECURE,'find_video_by_reference_id',options)
|
54
|
+
return self.parse(response)
|
55
|
+
else
|
56
|
+
options.merge!({:reference_ids => ids.join(',')})
|
57
|
+
response = get(SERVER,PORT,READ_PATH,SECURE,'find_videos_by_reference_ids',options)
|
58
|
+
return self.parse(response)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Find a video by text search. Invokes Brightcove Media API command 'find_videos_by_text'
|
63
|
+
#
|
64
|
+
# Encosion::Video.find_by_text('funny videos',:token => 'asdf')
|
65
|
+
|
66
|
+
def find_by_text(*args)
|
67
|
+
options = extract_options(args)
|
68
|
+
text = args.flatten.compact.uniq
|
69
|
+
raise AssetNotFound, "Couldn't find #{self.class} without text" if text == ''
|
70
|
+
options.merge!({:text => text.first})
|
71
|
+
response = get(SERVER,PORT,READ_PATH,SECURE,'find_videos_by_text',options)
|
72
|
+
return response['items'].collect { |item| self.parse(item) }
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Find videos related to the given video_id. Invokes Brightcove Media API command 'find_related_videos'
|
77
|
+
#
|
78
|
+
# Encosion::Video.find_related(123456,:token => 'asdf')
|
79
|
+
|
80
|
+
def find_related(*args)
|
81
|
+
options = extract_options(args)
|
82
|
+
raise AssetNotFound, "Cannot find related #{self.class}s without a video_id or reference_id" if options[:video_id].nil? && options[:reference_id].nil?
|
83
|
+
response = get(SERVER,PORT,READ_PATH,SECURE,'find_related_videos',options)
|
84
|
+
return response['items'].collect { |item| self.parse(item) }
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
# Find a video by tag search. Invokes Brightcove Media API command 'find_videos_by_tags'
|
89
|
+
#
|
90
|
+
# Encosion::Video.find_by_tags('bloopers','gagreel','funny',:token => 'asdf')
|
91
|
+
|
92
|
+
def find_by_tags(*args)
|
93
|
+
options = extract_options(args)
|
94
|
+
tags = args.flatten.compact.uniq
|
95
|
+
|
96
|
+
case tags.size
|
97
|
+
when 0
|
98
|
+
raise AssetNotFound, "Couldn't find #{self.class} without tags"
|
99
|
+
else
|
100
|
+
options.merge!({:and_tags => tags.join(',')})
|
101
|
+
response = get(SERVER,PORT,READ_PATH,SECURE,'find_videos_by_tags',options)
|
102
|
+
return response['items'].collect { |item| self.parse(item) }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
# Find some videos by ids
|
108
|
+
def find_one(id, options)
|
109
|
+
options.merge!({:video_id => id})
|
110
|
+
response = get(SERVER,PORT,READ_PATH,SECURE,'find_video_by_id',options)
|
111
|
+
return self.parse(response)
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
# Find mutliple videos by id
|
116
|
+
def find_some(ids, options)
|
117
|
+
options.merge!({:video_ids => ids.join(',')})
|
118
|
+
response = get(SERVER,PORT,READ_PATH,SECURE,'find_videos_by_ids',options)
|
119
|
+
puts response
|
120
|
+
return response['items'].collect { |item| self.parse(item) }
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# Find all videos
|
125
|
+
def find_all(options)
|
126
|
+
response = get(SERVER,PORT,READ_PATH,SECURE,'find_all_videos',options)
|
127
|
+
return response['items'].collect { |item| self.parse(item) }
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
# Creates a new Video object from a Ruby hash (used to create a video from a parsed API call)
|
132
|
+
def parse(obj)
|
133
|
+
args = {:id => obj['id'].to_i,
|
134
|
+
:name => obj['name'],
|
135
|
+
:short_description => obj['shortDescription'],
|
136
|
+
:long_description => obj['longDescription'],
|
137
|
+
:creation_date => Time.at(obj['creationDate'].to_i/1000),
|
138
|
+
:published_date => Time.at(obj['publishedDate'].to_i/1000),
|
139
|
+
:last_modified_date => Time.at(obj['lastModifiedDate'].to_i/1000),
|
140
|
+
:link_url => obj['linkURL'],
|
141
|
+
:link_text => obj['linkText'],
|
142
|
+
:tags => obj['tags'],
|
143
|
+
:video_still_url => obj['videoStillURL'],
|
144
|
+
:thumbnail_url => obj['thumbnailURL'],
|
145
|
+
:reference_id => obj['referenceID'],
|
146
|
+
:length => obj['length'].to_i,
|
147
|
+
:economics => obj['economics'] ? ENUMS[:economics].find { |key,value| value == obj['economics'] }.first : nil,
|
148
|
+
:plays_total => obj['playsTotal'].to_i,
|
149
|
+
:plays_trailing_week => obj['playsTrailingWeek'].to_i } unless obj.nil?
|
150
|
+
return self.new(args)
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
#
|
156
|
+
# Instance methods
|
157
|
+
#
|
158
|
+
def initialize(args={})
|
159
|
+
@id = args[:id]
|
160
|
+
@name = args[:name]
|
161
|
+
@short_description = args[:short_description]
|
162
|
+
@long_description = args[:long_description]
|
163
|
+
@creation_date = args[:creation_date]
|
164
|
+
@published_date = args[:published_date]
|
165
|
+
@last_modified_date = args[:last_modified_date]
|
166
|
+
@link_url = args[:link_url]
|
167
|
+
@link_text = args[:link_text]
|
168
|
+
@tags = args[:tags]
|
169
|
+
@video_still_url = args[:video_still_url]
|
170
|
+
@thumbnail_url = args[:thumbnail_url]
|
171
|
+
@reference_id = args[:reference_id]
|
172
|
+
@length = args[:length]
|
173
|
+
@economics = args[:economics]
|
174
|
+
@plays_total = args[:plays_total]
|
175
|
+
@plays_trailing_week = args[:plays_trailing_week]
|
176
|
+
@file = args[:file]
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
# Saves a video to Brightcove. Returns the Brightcove ID for the video that was just uploaded.
|
181
|
+
# new_video = Encosion::Video.new(:file => File.new('/path/to/file'), :name => "My Awesome Video", :short_description => "A video of some awesome happenings", :tags => ['awesome','sweet'])
|
182
|
+
# brightcove_id = new_video.save(:token => '123abc')
|
183
|
+
|
184
|
+
def save(args={})
|
185
|
+
# check to make sure we have everything needed for a create_video call
|
186
|
+
raise NoFile, "You need to attach a file to this video before you can upload it: Video.file = File.new('/path/to/file')" if @file.nil?
|
187
|
+
options = args.merge({ 'video' => self.to_brightcove }) # take the parameters of this video and make them a valid video object for upload
|
188
|
+
response = post(SERVER,PORT,WRITE_PATH,SECURE,'create_video',options,self)
|
189
|
+
return response['result'] # returns the Brightcove ID of the video that was just uploaded
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
# Output the video as JSON
|
194
|
+
def to_json
|
195
|
+
{ :id => @id,
|
196
|
+
:name => @name,
|
197
|
+
:short_description => @short_description,
|
198
|
+
:long_description => @long_description,
|
199
|
+
:creation_date => @creation_date,
|
200
|
+
:published_date => @published_date,
|
201
|
+
:last_modified_date => @last_modified_date,
|
202
|
+
:link_url => @link_url,
|
203
|
+
:link_text => @link_text,
|
204
|
+
:tags => @tags,
|
205
|
+
:video_still_url => @video_still_url,
|
206
|
+
:thumbnail_url => @thumbnail_url,
|
207
|
+
:reference_id => @reference_id,
|
208
|
+
:length => @length,
|
209
|
+
:economics => @economics,
|
210
|
+
:plays_total => @plays_total,
|
211
|
+
:plays_trailing_week => @plays_trailing_week }.to_json
|
212
|
+
end
|
213
|
+
|
214
|
+
# Outputs the video object into Brightcove's expected format
|
215
|
+
def to_brightcove
|
216
|
+
{ 'name' => @name,
|
217
|
+
'shortDescription' => @short_description,
|
218
|
+
'longDescription' => @long_description,
|
219
|
+
'linkURL' => @link_url,
|
220
|
+
'linkText' => @link_text,
|
221
|
+
'tags' => @tags,
|
222
|
+
'referenceId' => @reference_id,
|
223
|
+
'economics' => ENUMS[:economics][@economics] }
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
# Makes sure that the economics set on this video is one of a predetermined list
|
228
|
+
def encosion=(sym)
|
229
|
+
if ENUMS[:economics].has_key?(sym)
|
230
|
+
raise EncosionError::InvalidEconomicsValue, "A video's economics value must be one of #{ENUMS[:economics].collect { |key,value| e.key }.join(',')}"
|
231
|
+
else
|
232
|
+
@economics = sym
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
data/lib/encosion.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) # for use/testing when no gem is installed
|
2
|
+
|
3
|
+
# external
|
4
|
+
require 'net/http'
|
5
|
+
require 'net/https'
|
6
|
+
require 'uri'
|
7
|
+
require 'cgi'
|
8
|
+
require 'logger'
|
9
|
+
require 'json'
|
10
|
+
require 'yaml'
|
11
|
+
|
12
|
+
# internal
|
13
|
+
require 'encosion/base'
|
14
|
+
require 'encosion/video'
|
15
|
+
require 'encosion/playlist'
|
16
|
+
require 'encosion/exceptions'
|
17
|
+
|
18
|
+
module Encosion
|
19
|
+
|
20
|
+
VERSION = '0.1.3'
|
21
|
+
LOGGER = Logger.new(STDOUT)
|
22
|
+
|
23
|
+
def self.new(*args)
|
24
|
+
Engine.new(*args)
|
25
|
+
end
|
26
|
+
|
27
|
+
class Engine
|
28
|
+
|
29
|
+
SERVER = 'api.brightcove.com'
|
30
|
+
PORT = 80
|
31
|
+
PATH = '/services/library'
|
32
|
+
SECURE = false
|
33
|
+
DEFAULT_ARGS = { :read_token => nil, :write_token => nil }
|
34
|
+
DEFAULT_OPTIONS = { :debug => false }
|
35
|
+
|
36
|
+
attr_reader :read_token, :write_token
|
37
|
+
|
38
|
+
def initialize(options={})
|
39
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
40
|
+
@options[:read_token] = @options[:token] if @options[:token] # if there's only one token, assume it's a read
|
41
|
+
@read_token = @options[:read_token]
|
42
|
+
@write_token = @options[:write_token]
|
43
|
+
if @read_token.nil? && @write_token.nil?
|
44
|
+
raise EncosionError::TokenMissing, 'You must provide either a read or write token to use the Brightcove API'
|
45
|
+
end
|
46
|
+
|
47
|
+
#@http = Net::HTTP.new(SERVER, PORT)
|
48
|
+
#@http.use_ssl = SECURE
|
49
|
+
#@http.set_debug_output $stdout if @options[:debug]
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/test/movie.mov
ADDED
Binary file
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cannikin-encosion
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rob Cameron
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-07-07 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: httpclient
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.1.5.2
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: json
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.1.7
|
34
|
+
version:
|
35
|
+
description:
|
36
|
+
email: cannikinn@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README.rdoc
|
44
|
+
files:
|
45
|
+
- .document
|
46
|
+
- .gitignore
|
47
|
+
- LICENSE
|
48
|
+
- README.rdoc
|
49
|
+
- Rakefile
|
50
|
+
- VERSION
|
51
|
+
- encosion.gemspec
|
52
|
+
- lib/encosion.rb
|
53
|
+
- lib/encosion/base.rb
|
54
|
+
- lib/encosion/cue_point.rb
|
55
|
+
- lib/encosion/exceptions.rb
|
56
|
+
- lib/encosion/image.rb
|
57
|
+
- lib/encosion/playlist.rb
|
58
|
+
- lib/encosion/rendition.rb
|
59
|
+
- lib/encosion/video.rb
|
60
|
+
- test/encosion_test.rb
|
61
|
+
- test/movie.mov
|
62
|
+
- test/test_helper.rb
|
63
|
+
has_rdoc: false
|
64
|
+
homepage: http://github.com/cannikin/encosion
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options:
|
67
|
+
- --charset=UTF-8
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "0"
|
81
|
+
version:
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.2.0
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Ruby library for working with the Brightcove API
|
89
|
+
test_files:
|
90
|
+
- test/encosion_test.rb
|
91
|
+
- test/test_helper.rb
|