zencoder 2.1.15 → 2.2.0
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/bin/zencoder +3 -0
- data/lib/zencoder/cli/auth.rb +28 -0
- data/lib/zencoder/cli/command.rb +41 -0
- data/lib/zencoder/cli/commands/account.rb +42 -0
- data/lib/zencoder/cli/commands/base.rb +13 -0
- data/lib/zencoder/cli/commands/jobs.rb +133 -0
- data/lib/zencoder/cli/commands/outputs.rb +23 -0
- data/lib/zencoder/cli/commands/plugins.rb +43 -0
- data/lib/zencoder/cli/commands/setup.rb +72 -0
- data/lib/zencoder/cli/helpers.rb +61 -0
- data/lib/zencoder/cli/plugin.rb +76 -0
- data/lib/zencoder/cli/response.rb +18 -0
- data/lib/zencoder/cli.rb +63 -0
- data/lib/zencoder/extensions.rb +27 -15
- data/lib/zencoder/version.rb +1 -1
- data/lib/zencoder/zencoder.rb +6 -2
- metadata +62 -16
data/bin/zencoder
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module ZencoderCLI
|
4
|
+
module Auth
|
5
|
+
extend ZencoderCLI::Helpers
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def require_authentication(env)
|
9
|
+
Zencoder.api_key ||= retrieve_api_key(env)
|
10
|
+
end
|
11
|
+
|
12
|
+
def retrieve_api_key(env)
|
13
|
+
env = "production" if !env || env.blank?
|
14
|
+
if File.exist?("#{home_directory}/.zencoder/api-key")
|
15
|
+
keys = YAML.load_file("#{home_directory}/.zencoder/api-key")
|
16
|
+
if keys[env].present?
|
17
|
+
keys[env]
|
18
|
+
else
|
19
|
+
error "No API found for the #{env} environment. Either set the environment variable ZENCODER_API_KEY or run `zencoder setup`."
|
20
|
+
end
|
21
|
+
else
|
22
|
+
error "No API keys found. Either set the environment variable ZENCODER_API_KEY or run `zencoder setup`."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ZencoderCLI
|
2
|
+
module Command
|
3
|
+
extend ZencoderCLI::Helpers
|
4
|
+
|
5
|
+
class UnknownCommandName < RuntimeError; end
|
6
|
+
|
7
|
+
mattr_accessor :commands
|
8
|
+
self.commands = {}
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def run(command, args, global_options={}, command_options={})
|
13
|
+
ZencoderCLI::Auth.require_authentication(global_options[:environment]) unless command[/^setup/]
|
14
|
+
pieces = command.split(":")
|
15
|
+
if pieces.size == 1
|
16
|
+
method_name = :run
|
17
|
+
klass_name = pieces.first.camelize
|
18
|
+
else
|
19
|
+
method_name = pieces.pop
|
20
|
+
klass_name = pieces.map(&:camelize).join("::")
|
21
|
+
end
|
22
|
+
klass = "ZencoderCLI::Command::#{klass_name}".constantize
|
23
|
+
if klass.respond_to?(method_name)
|
24
|
+
klass.send(method_name, args, global_options, command_options)
|
25
|
+
else
|
26
|
+
raise UnknownCommandName
|
27
|
+
end
|
28
|
+
rescue UnknownCommandName, NameError => e
|
29
|
+
if e.class == UnknownCommandName || e.message[/uninitialized constant ZencoderCLI::Command::/]
|
30
|
+
error "There is no command named #{command}. Use --help for more information."
|
31
|
+
else
|
32
|
+
raise e
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
require 'zencoder/cli/commands/base'
|
41
|
+
Dir["#{File.dirname(__FILE__)}/commands/*.rb"].each { |c| require c }
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module ZencoderCLI::Command
|
2
|
+
class Account < Base
|
3
|
+
|
4
|
+
provides "account", { "account:show" => "Show account information",
|
5
|
+
"account:integration" => "Put your account in integration mode",
|
6
|
+
"account:live" => "Take your account out of integration mode" }
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def show(args, global_options, command_options)
|
11
|
+
account = Zencoder::Account.details(:base_url => Zencoder.base_url(global_options[:environment])).body
|
12
|
+
rows = []
|
13
|
+
rows << ["Minutes Used", account["minutes_used"]]
|
14
|
+
rows << ["Minutes Included", account["minutes_included"]]
|
15
|
+
rows << ["Account State", account["account_state"].titleize]
|
16
|
+
rows << ["Billing State", account["billing_state"].titleize]
|
17
|
+
rows << ["Plan", account["plan"]]
|
18
|
+
rows << ["Integration Mode", account["integration_mode"] ? "YES" : "NO"]
|
19
|
+
puts table([{ :value => "Account", :colspan => 2 }], *rows)
|
20
|
+
end
|
21
|
+
|
22
|
+
def integration(args, global_options, command_options)
|
23
|
+
response = Zencoder::Account.integration(:base_url => Zencoder.base_url(global_options[:environment]))
|
24
|
+
if response.success?
|
25
|
+
puts "Your account is now in integration mode."
|
26
|
+
else
|
27
|
+
puts "There was an unexpected problem."
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def live(args, global_options, command_options)
|
32
|
+
response = Zencoder::Account.live(:base_url => Zencoder.base_url(global_options[:environment]))
|
33
|
+
if response.success?
|
34
|
+
puts "Your account is now able to process live jobs."
|
35
|
+
else
|
36
|
+
puts "You cannot turn off integration mode for this account."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
module ZencoderCLI::Command
|
2
|
+
class Jobs < Base
|
3
|
+
|
4
|
+
provides "jobs", { "jobs:list" => { :description => "Lists the most recent jobs",
|
5
|
+
:options => proc{|t|
|
6
|
+
t.opt :number, "Number of jobs returned per page. Default 10.", :type => Integer
|
7
|
+
t.opt :page, "Jobs page number. Default 1.", :type => Integer
|
8
|
+
t.opt :long, "Will not truncate filenames.", :default => false
|
9
|
+
}},
|
10
|
+
"jobs:show" => "Show job details by ID",
|
11
|
+
"jobs:resubmit" => "Resubmit a job by ID",
|
12
|
+
"jobs:cancel" => "Cancels a job by ID",
|
13
|
+
"jobs:delete" => "Deletes a job by ID" }
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
def list(args, global_options, command_options)
|
18
|
+
jobs = Zencoder::Job.list(:base_url => Zencoder.base_url(global_options[:environment]), :per_page => command_options[:number] || 10, :page => command_options[:page] || 1).process_for_cli.body
|
19
|
+
if jobs.any?
|
20
|
+
jobs_table = table do |t|
|
21
|
+
t.headings = ["ID", "Created", "Filename", "Duration", "Size", "Test", "State"]
|
22
|
+
jobs.each do |job|
|
23
|
+
duration = job["job"]["input_media_file"]["duration_in_ms"] ? (job["job"]["input_media_file"]["duration_in_ms"]/1000).to_s+"s" : "---"
|
24
|
+
filesize = job["job"]["input_media_file"]["file_size_bytes"] ? ("%0.2f" % (job["job"]["input_media_file"]["file_size_bytes"].to_f/1.megabyte))+" MB" : "---"
|
25
|
+
t << [
|
26
|
+
job["job"]["id"],
|
27
|
+
format_date(job["job"]["created_at"]),
|
28
|
+
truncate(File.basename(job["job"]["input_media_file"]["url"]), :length => command_options[:long] ? 256 : 25),
|
29
|
+
{ :value => duration, :alignment => :right },
|
30
|
+
{ :value => filesize, :alignment => :right },
|
31
|
+
job["job"]["test"] ? "YES" : "NO",
|
32
|
+
job["job"]["state"].titleize
|
33
|
+
]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
puts jobs_table
|
37
|
+
else
|
38
|
+
puts "No jobs found."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def show(args, global_options, command_options)
|
43
|
+
job = Zencoder::Job.details(args.shift, :base_url => Zencoder.base_url(global_options[:environment])).process_for_cli.body["job"]
|
44
|
+
rows = []
|
45
|
+
rows << ["ID", job["id"]]
|
46
|
+
rows << ["Created", format_date(job["created_at"])]
|
47
|
+
rows << ["Finished", format_date(job["finished_at"])] if job["finished_at"]
|
48
|
+
rows << ["Pass Through", job["pass_through"]] if job["pass_through"]
|
49
|
+
rows << ["Test", job["test"] ? "YES" : "NO"]
|
50
|
+
rows << ["State", job["state"].titleize]
|
51
|
+
puts table([{ :value => "Job", :colspan => 2 }], *rows)
|
52
|
+
puts
|
53
|
+
|
54
|
+
input = job["input_media_file"]
|
55
|
+
rows = []
|
56
|
+
rows << ["ID", input["id"]]
|
57
|
+
rows << ["URL", input["url"]]
|
58
|
+
rows << ["State", input["state"].titleize]
|
59
|
+
rows << ["Duration", (input["duration_in_ms"]/1000).to_s+" seconds"] if input["duration_in_ms"]
|
60
|
+
rows << ["Size", ("%0.2f" % (input["file_size_bytes"].to_f/1.megabyte))+" MB"] if input["file_size_bytes"]
|
61
|
+
rows << ["Format", input["format"]] if input["format"]
|
62
|
+
if input["state"] == "finished"
|
63
|
+
rows << :separator
|
64
|
+
rows << ["Video Codec", input["video_codec"]] if input["video_codec"]
|
65
|
+
rows << ["Resolution", input["width"].to_s+"x"+input["height"].to_s] if input["width"] && input["height"]
|
66
|
+
rows << ["Video Bitrate", input["video_bitrate_in_kbps"].to_s+" Kbps"] if input["video_bitrate_in_kbps"]
|
67
|
+
rows << ["Frame Rate", input["frame_rate"]] if input["frame_rate"]
|
68
|
+
rows << :separator
|
69
|
+
rows << ["Audio Codec", input["audio_codec"]] if input["audio_codec"]
|
70
|
+
rows << ["Audio Bitrate", input["audio_bitrate_in_kbps"].to_s+" Kbps"] if input["audio_codec"]
|
71
|
+
rows << ["Sample Rate", input["audio_sample_rate"]] if input["audio_sample_rate"]
|
72
|
+
rows << ["Channels", input["channels"]] if input["channels"]
|
73
|
+
end
|
74
|
+
if input["error_class"] || input["error_message"]
|
75
|
+
rows << :separator
|
76
|
+
rows << ["Error Class", input["error_class"]] if input["error_class"]
|
77
|
+
rows << ["Error Message", input["error_message"]] if input["error_message"]
|
78
|
+
end
|
79
|
+
puts table([{ :value => "Input", :colspan => 2 }], *rows)
|
80
|
+
puts
|
81
|
+
|
82
|
+
job["output_media_files"].each_with_index do |output, i|
|
83
|
+
rows = []
|
84
|
+
rows << ["ID", output["id"]]
|
85
|
+
rows << ["Label", output["label"]] if output["label"]
|
86
|
+
rows << ["URL", output["url"]]
|
87
|
+
rows << ["State", output["state"].titleize]
|
88
|
+
rows << ["Duration", (output["duration_in_ms"]/1000).to_s+" seconds"] if output["duration_in_ms"]
|
89
|
+
rows << ["Size", ("%0.2f" % (output["file_size_bytes"].to_f/1.megabyte))+" MB"] if output["file_size_bytes"]
|
90
|
+
rows << ["Format", output["format"]] if output["format"]
|
91
|
+
if output["state"] == "finished"
|
92
|
+
rows << :separator
|
93
|
+
rows << ["Video Codec", output["video_codec"]] if output["video_codec"]
|
94
|
+
rows << ["Resolution", output["width"].to_s+"x"+output["height"].to_s] if output["width"] && output["height"]
|
95
|
+
rows << ["Video Bitrate", output["video_bitrate_in_kbps"].to_s+" Kbps"] if output["video_bitrate_in_kbps"]
|
96
|
+
rows << ["Frame Rate", output["frame_rate"]] if output["frame_rate"]
|
97
|
+
rows << :separator
|
98
|
+
rows << ["Audio Codec", output["audio_codec"]] if output["audio_codec"]
|
99
|
+
rows << ["Audio Bitrate", output["audio_bitrate_in_kbps"].to_s+" Kbps"] if output["audio_codec"]
|
100
|
+
rows << ["Sample Rate", output["audio_sample_rate"]] if output["audio_sample_rate"]
|
101
|
+
rows << ["Channels", output["channels"]] if output["channels"]
|
102
|
+
end
|
103
|
+
if output["error_class"] || output["error_message"]
|
104
|
+
rows << :separator
|
105
|
+
rows << ["Error Class", output["error_class"]] if output["error_class"]
|
106
|
+
rows << ["Error Message", output["error_message"]] if output["error_message"]
|
107
|
+
end
|
108
|
+
puts table([{ :value => "Output ##{i+1}", :colspan => 2 }], *rows)
|
109
|
+
puts
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def resubmit(args, global_options, command_options)
|
114
|
+
job_id = args.shift
|
115
|
+
response = Zencoder::Job.resubmit(job_id, :base_url => Zencoder.base_url(global_options[:environment])).process_for_cli
|
116
|
+
puts "Job ##{job_id} resubmitted."
|
117
|
+
end
|
118
|
+
|
119
|
+
def cancel(args, global_options, command_options)
|
120
|
+
job_id = args.shift
|
121
|
+
response = Zencoder::Job.cancel(job_id, :base_url => Zencoder.base_url(global_options[:environment])).process_for_cli
|
122
|
+
puts "Job ##{job_id} cancelled."
|
123
|
+
end
|
124
|
+
|
125
|
+
def delete(args, global_options, command_options)
|
126
|
+
job_id = args.shift
|
127
|
+
response = Zencoder::Job.delete(job_id, :base_url => Zencoder.base_url(global_options[:environment])).process_for_cli
|
128
|
+
puts "Job ##{job_id} deleted."
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ZencoderCLI::Command
|
2
|
+
class Outputs < Base
|
3
|
+
|
4
|
+
provides "outputs", { "outputs:progress" => "Show output progress" }
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def progress(args, global_options, command_options)
|
9
|
+
output = Zencoder::Output.progress(args.shift, :base_url => Zencoder.base_url(global_options[:environment])).process_for_cli.body
|
10
|
+
rows = []
|
11
|
+
rows << ["State", output["state"].titleize]
|
12
|
+
if output["state"] == "processing"
|
13
|
+
rows << ["Event", output["current_event"].titleize]
|
14
|
+
rows << ["Progress", output["progress"]]
|
15
|
+
elsif output["state"] == "finished"
|
16
|
+
rows << ["Progress", "100%"]
|
17
|
+
end
|
18
|
+
puts table([{ :value => "Output", :colspan => 2 }], *rows)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ZencoderCLI::Command
|
2
|
+
class Plugins < Base
|
3
|
+
|
4
|
+
provides "plugins", { "plugins:list" => "Lists installed plugins",
|
5
|
+
"plugins:install" => "Install a plugin via URL",
|
6
|
+
"plugins:uninstall" => "Uninstall a plugin" }
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def list(args, global_options, command_options)
|
11
|
+
if ZencoderCLI::Plugin.list.any?
|
12
|
+
puts "The following plugins are installed:"
|
13
|
+
ZencoderCLI::Plugin.list.each do |plugin|
|
14
|
+
display "* #{plugin}"
|
15
|
+
end
|
16
|
+
else
|
17
|
+
display "There are no plugins installed."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def install(args, global_options, command_options)
|
22
|
+
plugin = ZencoderCLI::Plugin.new(args.shift)
|
23
|
+
if plugin.install
|
24
|
+
begin
|
25
|
+
ZencoderCLI::Plugin.load_plugin(plugin.name)
|
26
|
+
rescue Exception => e
|
27
|
+
installation_failed(plugin, e.message)
|
28
|
+
end
|
29
|
+
display "#{plugin} installed."
|
30
|
+
else
|
31
|
+
error "Could not install #{plugin}. Please check the URL and try again."
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def uninstall(args, global_options, command_options)
|
36
|
+
plugin = ZencoderCLI::Plugin.new(args.shift)
|
37
|
+
plugin.uninstall
|
38
|
+
display "#{plugin} uninstalled."
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module ZencoderCLI::Command
|
5
|
+
class Setup < Base
|
6
|
+
|
7
|
+
provides "setup", { "setup" => "Caches authentication credentials",
|
8
|
+
"setup:show" => "Shows your API keys",
|
9
|
+
"setup:delete" => "Removes cached credentials and plugins" }
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def run(args, global_options, command_options)
|
14
|
+
display("Enter Your Zencoder API Key: ", false)
|
15
|
+
save_api_key(global_options[:environment], ask)
|
16
|
+
display "Your API key has been saved to #{home_directory}/.zencoder/api-key."
|
17
|
+
end
|
18
|
+
|
19
|
+
def show(args, global_options, command_options)
|
20
|
+
if File.exist?("#{home_directory}/.zencoder/api-key")
|
21
|
+
keys = YAML.load_file("#{home_directory}/.zencoder/api-key")
|
22
|
+
if keys.length == 1
|
23
|
+
display("Your API Key: ", false)
|
24
|
+
puts keys.values.first
|
25
|
+
else
|
26
|
+
display("Your API Keys: ")
|
27
|
+
puts table(nil, *keys.to_a)
|
28
|
+
end
|
29
|
+
else
|
30
|
+
display("You have no API keys stored. Run `zencoder setup` to get started.")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete(args, global_options, command_options)
|
35
|
+
if confirm
|
36
|
+
delete_setup
|
37
|
+
display "#{home_directory}/.zencoder has been removed."
|
38
|
+
else
|
39
|
+
display "Ok, nothing changed."
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def save_api_key(environment, api_key)
|
47
|
+
environment = "production" if !environment || environment.blank?
|
48
|
+
begin
|
49
|
+
FileUtils.mkdir_p("#{home_directory}/.zencoder")
|
50
|
+
if File.exist?("#{home_directory}/.zencoder/api-key")
|
51
|
+
key_envs = YAML.load_file("#{home_directory}/.zencoder/api-key")
|
52
|
+
else
|
53
|
+
key_envs = {}
|
54
|
+
end
|
55
|
+
key_envs[environment] = api_key
|
56
|
+
File.open("#{home_directory}/.zencoder/api-key", 'w') do |out|
|
57
|
+
YAML.dump(key_envs, out)
|
58
|
+
end
|
59
|
+
FileUtils.chmod 0700, "#{home_directory}/.zencoder"
|
60
|
+
FileUtils.chmod 0600, "#{home_directory}/.zencoder/api-key"
|
61
|
+
rescue Exception => e
|
62
|
+
raise e
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def delete_setup
|
67
|
+
FileUtils.rm_rf("#{home_directory}/.zencoder") if File.exist?("#{home_directory}/.zencoder")
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Thank you Heroku gem.
|
2
|
+
|
3
|
+
module ZencoderCLI
|
4
|
+
module Helpers
|
5
|
+
|
6
|
+
def home_directory
|
7
|
+
running_on_windows? ? ENV['USERPROFILE'] : ENV['HOME']
|
8
|
+
end
|
9
|
+
|
10
|
+
def running_on_windows?
|
11
|
+
RUBY_PLATFORM =~ /mswin32|mingw32/
|
12
|
+
end
|
13
|
+
|
14
|
+
def running_on_a_mac?
|
15
|
+
RUBY_PLATFORM =~ /-darwin\d/
|
16
|
+
end
|
17
|
+
|
18
|
+
def format_date(date)
|
19
|
+
date = Time.parse(date) if date.is_a?(String)
|
20
|
+
date.strftime("%Y-%m-%d %H:%M %Z")
|
21
|
+
end
|
22
|
+
|
23
|
+
def display(msg, newline=true)
|
24
|
+
if newline
|
25
|
+
puts(msg)
|
26
|
+
else
|
27
|
+
print(msg)
|
28
|
+
STDOUT.flush
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def error(msg)
|
33
|
+
STDERR.puts(msg)
|
34
|
+
exit 1
|
35
|
+
end
|
36
|
+
|
37
|
+
def confirm(message="Are you sure you wish to continue? (y/N)?")
|
38
|
+
display("#{message} ", false)
|
39
|
+
ask.downcase == 'y'
|
40
|
+
end
|
41
|
+
|
42
|
+
def ask
|
43
|
+
gets.strip
|
44
|
+
rescue Interrupt
|
45
|
+
puts
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
|
49
|
+
def truncate(text, *args)
|
50
|
+
options = args.extract_options!
|
51
|
+
options.reverse_merge!(:length => 30, :omission => "...")
|
52
|
+
|
53
|
+
if text
|
54
|
+
l = options[:length] - options[:omission].mb_chars.length
|
55
|
+
chars = text.mb_chars
|
56
|
+
(chars.length > options[:length] ? chars[0...l] + options[:omission] : text).to_s
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# based on the Rails Plugin
|
2
|
+
|
3
|
+
module ZencoderCLI
|
4
|
+
class Plugin
|
5
|
+
class << self
|
6
|
+
include ZencoderCLI::Helpers
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :name, :uri
|
10
|
+
|
11
|
+
def self.directory
|
12
|
+
File.expand_path("#{home_directory}/.zencoder/plugins")
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.list
|
16
|
+
Dir["#{directory}/*"].sort.map do |folder|
|
17
|
+
File.basename(folder)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.load!
|
22
|
+
list.each do |plugin|
|
23
|
+
begin
|
24
|
+
load_plugin(plugin)
|
25
|
+
rescue Exception => e
|
26
|
+
display "Unable to load plugin: #{plugin}: #{e.message}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.load_plugin(plugin)
|
32
|
+
folder = "#{self.directory}/#{plugin}"
|
33
|
+
$: << "#{folder}/lib" if File.directory? "#{folder}/lib"
|
34
|
+
load "#{folder}/init.rb" if File.exists? "#{folder}/init.rb"
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(uri)
|
38
|
+
@uri = uri
|
39
|
+
guess_name(uri)
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
name
|
44
|
+
end
|
45
|
+
|
46
|
+
def path
|
47
|
+
"#{self.class.directory}/#{name}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def install
|
51
|
+
FileUtils.mkdir_p(path)
|
52
|
+
Dir.chdir(path) do
|
53
|
+
system("git init -q")
|
54
|
+
if !system("git pull #{uri} -q")
|
55
|
+
FileUtils.rm_rf path
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def uninstall
|
63
|
+
FileUtils.rm_r path if File.directory?(path)
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def guess_name(url)
|
70
|
+
@name = File.basename(url)
|
71
|
+
@name = File.basename(File.dirname(url)) if @name.empty?
|
72
|
+
@name.gsub!(/\.git$/, '') if @name =~ /\.git$/
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Zencoder
|
2
|
+
class Response < Zencoder
|
3
|
+
|
4
|
+
def process_for_cli
|
5
|
+
if success?
|
6
|
+
self
|
7
|
+
else
|
8
|
+
if errors.any?
|
9
|
+
puts "Errors:\n#{errors.map{|error| "* "+error }.join("\n")}"
|
10
|
+
else
|
11
|
+
puts "ERROR\n-----\n\n#{body}\n\nHTTP Response Code\n------------------\n#{code}"
|
12
|
+
end
|
13
|
+
exit(1)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/lib/zencoder/cli.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'trollop'
|
3
|
+
require 'terminal-table/import'
|
4
|
+
require 'zencoder'
|
5
|
+
require 'zencoder/cli/helpers'
|
6
|
+
require 'zencoder/cli/auth'
|
7
|
+
require 'zencoder/cli/plugin'
|
8
|
+
require 'zencoder/cli/command'
|
9
|
+
require 'zencoder/cli/response'
|
10
|
+
ZencoderCLI::Plugin.load!
|
11
|
+
|
12
|
+
global_options = Trollop::options do
|
13
|
+
version "Zencoder #{Zencoder::GEM_VERSION}"
|
14
|
+
banner <<-EOS
|
15
|
+
#{"-" * (14 + Zencoder::GEM_VERSION.length)}
|
16
|
+
Zencoder CLI v#{Zencoder::GEM_VERSION}
|
17
|
+
#{"-" * (14 + Zencoder::GEM_VERSION.length)}
|
18
|
+
|
19
|
+
== Usage
|
20
|
+
|
21
|
+
zencoder [global-options] command [command-options]
|
22
|
+
|
23
|
+
== Available Commands
|
24
|
+
|
25
|
+
#{
|
26
|
+
ZencoderCLI::Command.commands.sort.map{|group, commands|
|
27
|
+
commands.map{|command, description|
|
28
|
+
command.ljust(22)+" # "+(description.is_a?(String) ? description : description[:description])
|
29
|
+
}.join("\n")
|
30
|
+
}.join("\n\n")
|
31
|
+
}
|
32
|
+
|
33
|
+
== Global Options
|
34
|
+
EOS
|
35
|
+
opt :environment, "Sets the environment to use (optional: defaults to production)", :type => String
|
36
|
+
stop_on ZencoderCLI::Command.commands.map{|k, v| v.keys }.flatten
|
37
|
+
end
|
38
|
+
|
39
|
+
if ARGV.empty?
|
40
|
+
puts "You must specify a command. Use --help for more information."
|
41
|
+
exit(1)
|
42
|
+
end
|
43
|
+
|
44
|
+
command = ARGV.shift.strip
|
45
|
+
args = ARGV
|
46
|
+
|
47
|
+
|
48
|
+
flat_commands = ZencoderCLI::Command.commands.values.inject({}){|memo,group| memo.merge!(group) }
|
49
|
+
command_options = Trollop::options do
|
50
|
+
banner <<-EOS
|
51
|
+
== Usage
|
52
|
+
|
53
|
+
zencoder [global-options] #{command} [options]
|
54
|
+
|
55
|
+
== Command Options
|
56
|
+
EOS
|
57
|
+
if flat_commands[command] && flat_commands[command][:options]
|
58
|
+
flat_commands[command][:options].call(self)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
ZencoderCLI::Command.run(command, args, global_options, command_options)
|
data/lib/zencoder/extensions.rb
CHANGED
@@ -1,27 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
unless Hash.method_defined?(:recursive_with_indifferent_access)
|
2
|
+
class Hash
|
3
|
+
def recursive_with_indifferent_access
|
4
|
+
hash = with_indifferent_access
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
hash.each do |key, value|
|
7
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
8
|
+
hash[key] = value.recursive_with_indifferent_access
|
9
|
+
end
|
8
10
|
end
|
9
|
-
end
|
10
11
|
|
11
|
-
|
12
|
+
hash
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
unless Array.method_defined?(:recursive_with_indifferent_access)
|
18
|
+
class Array
|
19
|
+
def recursive_with_indifferent_access
|
20
|
+
array = dup
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
array.each_with_index do |value, index|
|
23
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
24
|
+
array[index] = value.recursive_with_indifferent_access
|
25
|
+
end
|
22
26
|
end
|
27
|
+
|
28
|
+
array
|
23
29
|
end
|
30
|
+
end
|
31
|
+
end
|
24
32
|
|
25
|
-
|
33
|
+
unless String.method_defined?(:shell_escape)
|
34
|
+
class String
|
35
|
+
def shell_escape
|
36
|
+
empty? ? "''" : gsub(/([^A-Za-z0-9_\-.,:\/@\n])/n, '\\\\\\1').gsub(/\n/, "'\n'")
|
37
|
+
end
|
26
38
|
end
|
27
39
|
end
|
data/lib/zencoder/version.rb
CHANGED
data/lib/zencoder/zencoder.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Zencoder
|
2
2
|
|
3
|
-
|
3
|
+
cattr_writer :base_url
|
4
4
|
cattr_writer :api_key
|
5
5
|
|
6
6
|
def self.api_key
|
@@ -8,7 +8,11 @@ class Zencoder
|
|
8
8
|
end
|
9
9
|
|
10
10
|
self.base_url = 'https://app.zencoder.com/api'
|
11
|
-
|
11
|
+
|
12
|
+
def self.base_url(env=nil)
|
13
|
+
@@base_url
|
14
|
+
end
|
15
|
+
|
12
16
|
def self.encode(content, format=nil)
|
13
17
|
if content.is_a?(String)
|
14
18
|
content
|
metadata
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zencoder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 2.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 2.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Nathan Sutton
|
14
|
+
- Brandon Arbini
|
14
15
|
autorequire:
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2010-
|
19
|
+
date: 2010-11-16 00:00:00 -06:00
|
19
20
|
default_executable:
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
@@ -33,9 +34,41 @@ dependencies:
|
|
33
34
|
type: :runtime
|
34
35
|
version_requirements: *id001
|
35
36
|
- !ruby/object:Gem::Dependency
|
36
|
-
name:
|
37
|
+
name: trollop
|
37
38
|
prerelease: false
|
38
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 83
|
45
|
+
segments:
|
46
|
+
- 1
|
47
|
+
- 16
|
48
|
+
- 2
|
49
|
+
version: 1.16.2
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: terminal-table
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 1
|
63
|
+
- 4
|
64
|
+
- 2
|
65
|
+
version: 1.4.2
|
66
|
+
type: :runtime
|
67
|
+
version_requirements: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: shoulda
|
70
|
+
prerelease: false
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
39
72
|
none: false
|
40
73
|
requirements:
|
41
74
|
- - ">="
|
@@ -45,11 +78,11 @@ dependencies:
|
|
45
78
|
- 0
|
46
79
|
version: "0"
|
47
80
|
type: :development
|
48
|
-
version_requirements: *
|
81
|
+
version_requirements: *id004
|
49
82
|
- !ruby/object:Gem::Dependency
|
50
83
|
name: mocha
|
51
84
|
prerelease: false
|
52
|
-
requirement: &
|
85
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
53
86
|
none: false
|
54
87
|
requirements:
|
55
88
|
- - ">="
|
@@ -59,11 +92,11 @@ dependencies:
|
|
59
92
|
- 0
|
60
93
|
version: "0"
|
61
94
|
type: :development
|
62
|
-
version_requirements: *
|
95
|
+
version_requirements: *id005
|
63
96
|
- !ruby/object:Gem::Dependency
|
64
97
|
name: webmock
|
65
98
|
prerelease: false
|
66
|
-
requirement: &
|
99
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
67
100
|
none: false
|
68
101
|
requirements:
|
69
102
|
- - ">="
|
@@ -73,17 +106,30 @@ dependencies:
|
|
73
106
|
- 0
|
74
107
|
version: "0"
|
75
108
|
type: :development
|
76
|
-
version_requirements: *
|
77
|
-
description: Zencoder <http://zencoder.com> integration library.
|
78
|
-
email:
|
79
|
-
executables:
|
80
|
-
|
109
|
+
version_requirements: *id006
|
110
|
+
description: Zencoder <http://zencoder.com> integration library and CLI client.
|
111
|
+
email: info@zencoder.com
|
112
|
+
executables:
|
113
|
+
- zencoder
|
81
114
|
extensions: []
|
82
115
|
|
83
116
|
extra_rdoc_files: []
|
84
117
|
|
85
118
|
files:
|
119
|
+
- bin/zencoder
|
86
120
|
- lib/zencoder/account.rb
|
121
|
+
- lib/zencoder/cli/auth.rb
|
122
|
+
- lib/zencoder/cli/command.rb
|
123
|
+
- lib/zencoder/cli/commands/account.rb
|
124
|
+
- lib/zencoder/cli/commands/base.rb
|
125
|
+
- lib/zencoder/cli/commands/jobs.rb
|
126
|
+
- lib/zencoder/cli/commands/outputs.rb
|
127
|
+
- lib/zencoder/cli/commands/plugins.rb
|
128
|
+
- lib/zencoder/cli/commands/setup.rb
|
129
|
+
- lib/zencoder/cli/helpers.rb
|
130
|
+
- lib/zencoder/cli/plugin.rb
|
131
|
+
- lib/zencoder/cli/response.rb
|
132
|
+
- lib/zencoder/cli.rb
|
87
133
|
- lib/zencoder/errors.rb
|
88
134
|
- lib/zencoder/extensions.rb
|
89
135
|
- lib/zencoder/http/net_http.rb
|
@@ -132,6 +178,6 @@ rubyforge_project: zencoder
|
|
132
178
|
rubygems_version: 1.3.7
|
133
179
|
signing_key:
|
134
180
|
specification_version: 3
|
135
|
-
summary: Zencoder <http://zencoder.com> integration library.
|
181
|
+
summary: Zencoder <http://zencoder.com> integration library and CLI client.
|
136
182
|
test_files: []
|
137
183
|
|