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 ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path("#{File.dirname(__FILE__)}/../lib")
3
+ require 'zencoder/cli'
@@ -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,13 @@
1
+ module ZencoderCLI::Command
2
+ class Base
3
+ extend ZencoderCLI::Helpers
4
+
5
+ class << self
6
+
7
+ def provides(name, commands={})
8
+ ZencoderCLI::Command.commands.merge!({ name => commands })
9
+ end
10
+
11
+ end
12
+ end
13
+ 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
@@ -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)
@@ -1,27 +1,39 @@
1
- class Hash
2
- def recursive_with_indifferent_access
3
- hash = with_indifferent_access
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
- hash.each do |key, value|
6
- if value.is_a?(Hash) || value.is_a?(Array)
7
- hash[key] = value.recursive_with_indifferent_access
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
- hash
12
+ hash
13
+ end
12
14
  end
13
15
  end
14
16
 
15
- class Array
16
- def recursive_with_indifferent_access
17
- array = dup
17
+ unless Array.method_defined?(:recursive_with_indifferent_access)
18
+ class Array
19
+ def recursive_with_indifferent_access
20
+ array = dup
18
21
 
19
- array.each_with_index do |value, index|
20
- if value.is_a?(Hash) || value.is_a?(Array)
21
- array[index] = value.recursive_with_indifferent_access
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
- array
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
@@ -1,3 +1,3 @@
1
1
  class Zencoder
2
- GEM_VERSION = '2.1.15'
2
+ GEM_VERSION = '2.2.0'
3
3
  end
@@ -1,6 +1,6 @@
1
1
  class Zencoder
2
2
 
3
- cattr_accessor :base_url
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: 21
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
- - 1
9
- - 15
10
- version: 2.1.15
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-09-10 00:00:00 -07:00
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: shoulda
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: *id002
81
+ version_requirements: *id004
49
82
  - !ruby/object:Gem::Dependency
50
83
  name: mocha
51
84
  prerelease: false
52
- requirement: &id003 !ruby/object:Gem::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: *id003
95
+ version_requirements: *id005
63
96
  - !ruby/object:Gem::Dependency
64
97
  name: webmock
65
98
  prerelease: false
66
- requirement: &id004 !ruby/object:Gem::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: *id004
77
- description: Zencoder <http://zencoder.com> integration library.
78
- email: nate@zencoder.com
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