zencoder-cli 0.1.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/LICENSE +20 -0
- data/README.markdown +3 -0
- data/bin/zencoder +3 -0
- data/lib/zencoder-cli.rb +13 -0
- data/lib/zencoder-cli/auth.rb +28 -0
- data/lib/zencoder-cli/cli.rb +54 -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 +74 -0
- data/lib/zencoder-cli/response.rb +18 -0
- data/lib/zencoder-cli/version.rb +5 -0
- metadata +130 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Zencoder, Inc.
|
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
data/bin/zencoder
ADDED
data/lib/zencoder-cli.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'trollop'
|
3
|
+
require 'terminal-table/import'
|
4
|
+
|
5
|
+
require 'zencoder'
|
6
|
+
|
7
|
+
require 'zencoder-cli/version'
|
8
|
+
require 'zencoder-cli/helpers'
|
9
|
+
require 'zencoder-cli/auth'
|
10
|
+
require 'zencoder-cli/plugin'
|
11
|
+
require 'zencoder-cli/command'
|
12
|
+
require 'zencoder-cli/response'
|
13
|
+
require 'zencoder-cli/cli'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Zencoder::CLI
|
4
|
+
module Auth
|
5
|
+
extend Zencoder::CLI::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,54 @@
|
|
1
|
+
Zencoder::CLI::Plugin.load!
|
2
|
+
|
3
|
+
global_options = Trollop::options do
|
4
|
+
version "Zencoder #{Zencoder::CLI::GEM_VERSION}"
|
5
|
+
banner <<-EOS
|
6
|
+
#{"-" * (14 + Zencoder::CLI::GEM_VERSION.length)}
|
7
|
+
Zencoder CLI v#{Zencoder::CLI::GEM_VERSION}
|
8
|
+
#{"-" * (14 + Zencoder::CLI::GEM_VERSION.length)}
|
9
|
+
|
10
|
+
== Usage
|
11
|
+
|
12
|
+
zencoder [global-options] command [command-options]
|
13
|
+
|
14
|
+
== Available Commands
|
15
|
+
|
16
|
+
#{
|
17
|
+
Zencoder::CLI::Command.commands.sort.map{|group, commands|
|
18
|
+
commands.map{|command, description|
|
19
|
+
command.ljust(22)+" # "+(description.is_a?(String) ? description : description[:description])
|
20
|
+
}.join("\n")
|
21
|
+
}.join("\n\n")
|
22
|
+
}
|
23
|
+
|
24
|
+
== Global Options
|
25
|
+
EOS
|
26
|
+
opt :environment, "Sets the environment to use (optional: defaults to production)", :type => String
|
27
|
+
stop_on Zencoder::CLI::Command.commands.map{|k, v| v.keys }.flatten
|
28
|
+
end
|
29
|
+
|
30
|
+
if ARGV.empty?
|
31
|
+
puts "You must specify a command. Use --help for more information."
|
32
|
+
exit(1)
|
33
|
+
end
|
34
|
+
|
35
|
+
command = ARGV.shift.strip
|
36
|
+
args = ARGV
|
37
|
+
|
38
|
+
|
39
|
+
flat_commands = Zencoder::CLI::Command.commands.values.inject({}){|memo,group| memo.merge!(group) }
|
40
|
+
command_options = Trollop::options do
|
41
|
+
banner <<-EOS
|
42
|
+
== Usage
|
43
|
+
|
44
|
+
zencoder [global-options] #{command} [options]
|
45
|
+
|
46
|
+
== Command Options
|
47
|
+
EOS
|
48
|
+
if flat_commands[command] && flat_commands[command][:options]
|
49
|
+
flat_commands[command][:options].call(self)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
Zencoder::CLI::Command.run(command, args, global_options, command_options)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Zencoder::CLI
|
2
|
+
module Command
|
3
|
+
extend Zencoder::CLI::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
|
+
Zencoder::CLI::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 = "Zencoder::CLI::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 Zencoder::CLI::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 Zencoder::CLI::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 Zencoder::CLI::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 Zencoder::CLI::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 Zencoder::CLI::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 Zencoder::CLI::Plugin.list.any?
|
12
|
+
puts "The following plugins are installed:"
|
13
|
+
Zencoder::CLI::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 = Zencoder::CLI::Plugin.new(args.shift)
|
23
|
+
if plugin.install
|
24
|
+
begin
|
25
|
+
Zencoder::CLI::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 = Zencoder::CLI::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 Zencoder::CLI::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 Zencoder::CLI
|
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,74 @@
|
|
1
|
+
# based on the Rails Plugin
|
2
|
+
|
3
|
+
module Zencoder::CLI
|
4
|
+
class Plugin
|
5
|
+
extend Zencoder::CLI::Helpers
|
6
|
+
|
7
|
+
attr_reader :name, :uri
|
8
|
+
|
9
|
+
def self.directory
|
10
|
+
File.expand_path("#{home_directory}/.zencoder/plugins")
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.list
|
14
|
+
Dir["#{directory}/*"].sort.map do |folder|
|
15
|
+
File.basename(folder)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.load!
|
20
|
+
list.each do |plugin|
|
21
|
+
begin
|
22
|
+
load_plugin(plugin)
|
23
|
+
rescue Exception => e
|
24
|
+
display "Unable to load plugin: #{plugin}: #{e.message}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.load_plugin(plugin)
|
30
|
+
folder = "#{self.directory}/#{plugin}"
|
31
|
+
$: << "#{folder}/lib" if File.directory? "#{folder}/lib"
|
32
|
+
load "#{folder}/init.rb" if File.exists? "#{folder}/init.rb"
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(uri)
|
36
|
+
@uri = uri
|
37
|
+
guess_name(uri)
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
name
|
42
|
+
end
|
43
|
+
|
44
|
+
def path
|
45
|
+
"#{self.class.directory}/#{name}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def install
|
49
|
+
FileUtils.mkdir_p(path)
|
50
|
+
Dir.chdir(path) do
|
51
|
+
system("git init -q")
|
52
|
+
if !system("git pull #{uri} -q")
|
53
|
+
FileUtils.rm_rf path
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
|
+
def uninstall
|
61
|
+
FileUtils.rm_r path if File.directory?(path)
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def guess_name(url)
|
68
|
+
@name = File.basename(url)
|
69
|
+
@name = File.basename(File.dirname(url)) if @name.empty?
|
70
|
+
@name.gsub!(/\.git$/, '') if @name =~ /\.git$/
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Zencoder
|
2
|
+
class Response < Base
|
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
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zencoder-cli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Brandon Arbini
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-17 00:00:00 -06:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: zencoder
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 3
|
33
|
+
- 0
|
34
|
+
version: 2.3.0
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: trollop
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 83
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 16
|
49
|
+
- 2
|
50
|
+
version: 1.16.2
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: terminal-table
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 3
|
62
|
+
segments:
|
63
|
+
- 1
|
64
|
+
- 4
|
65
|
+
- 2
|
66
|
+
version: 1.4.2
|
67
|
+
type: :runtime
|
68
|
+
version_requirements: *id003
|
69
|
+
description: Zencoder <http://zencoder.com> CLI client.
|
70
|
+
email: info@zencoder.com
|
71
|
+
executables:
|
72
|
+
- zencoder
|
73
|
+
extensions: []
|
74
|
+
|
75
|
+
extra_rdoc_files: []
|
76
|
+
|
77
|
+
files:
|
78
|
+
- bin/zencoder
|
79
|
+
- lib/zencoder-cli/auth.rb
|
80
|
+
- lib/zencoder-cli/cli.rb
|
81
|
+
- lib/zencoder-cli/command.rb
|
82
|
+
- lib/zencoder-cli/commands/account.rb
|
83
|
+
- lib/zencoder-cli/commands/base.rb
|
84
|
+
- lib/zencoder-cli/commands/jobs.rb
|
85
|
+
- lib/zencoder-cli/commands/outputs.rb
|
86
|
+
- lib/zencoder-cli/commands/plugins.rb
|
87
|
+
- lib/zencoder-cli/commands/setup.rb
|
88
|
+
- lib/zencoder-cli/helpers.rb
|
89
|
+
- lib/zencoder-cli/plugin.rb
|
90
|
+
- lib/zencoder-cli/response.rb
|
91
|
+
- lib/zencoder-cli/version.rb
|
92
|
+
- lib/zencoder-cli.rb
|
93
|
+
- LICENSE
|
94
|
+
- README.markdown
|
95
|
+
has_rdoc: true
|
96
|
+
homepage: http://github.com/zencoder/zencoder-cli
|
97
|
+
licenses: []
|
98
|
+
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: 3
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
version: "0"
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
hash: 3
|
119
|
+
segments:
|
120
|
+
- 0
|
121
|
+
version: "0"
|
122
|
+
requirements: []
|
123
|
+
|
124
|
+
rubyforge_project: zencoder-cli
|
125
|
+
rubygems_version: 1.3.7
|
126
|
+
signing_key:
|
127
|
+
specification_version: 3
|
128
|
+
summary: Zencoder <http://zencoder.com> CLI client.
|
129
|
+
test_files: []
|
130
|
+
|