Class: Cifrado::CLI
- Inherits:
-
Thor
- Object
- Thor
- Cifrado::CLI
- Defined in:
- lib/cifrado/cli.rb,
lib/cifrado/cli/list.rb,
lib/cifrado/cli/post.rb,
lib/cifrado/cli/saio.rb,
lib/cifrado/cli/stat.rb,
lib/cifrado/cli/setup.rb,
lib/cifrado/cli/cinema.rb,
lib/cifrado/cli/delete.rb,
lib/cifrado/cli/upload.rb,
lib/cifrado/cli/configs.rb,
lib/cifrado/cli/jukebox.rb,
lib/cifrado/cli/set_acl.rb,
lib/cifrado/cli/version.rb,
lib/cifrado/cli/download.rb
Constant Summary
Constants included from Cifrado
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
Instance Method Summary collapse
- #cinema(container, video) ⇒ Object
- #configs ⇒ Object
- #delete(container, object = nil) ⇒ Object
- #download(container, object = nil) ⇒ Object
- #jukebox(container) ⇒ Object
- #list(container = nil) ⇒ Object
- #post(container, description = '') ⇒ Object
- #set_acl(container, object = nil) ⇒ Object
- #setup ⇒ Object
- #stat(container = nil, object = nil) ⇒ Object
- #upload(container, *args) ⇒ Object
- #version ⇒ Object
Methods included from Utils
#calculate_chunks, #clean_object_name, #decrypt_filename, #encrypt_filename, #humanize_bytes, #mime_type, #prettify_backtrace, #unix_time
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
7 8 9 |
# File 'lib/cifrado/cli.rb', line 7 def config @config end |
Instance Method Details
#cinema(container, video) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/cifrado/cli/cinema.rb', line 7 def cinema(container, video) client = client_instance dir = client.service.directories.get container unless dir raise "Container #{container} not found." end to_play = dir.files.find { |v| v.key =~ /#{video}/ } unless to_play raise "No video matches #{video}" end sub_file = nil if [:subtitles] begin Log.info "Subtitles found, downloading." sub_object = to_play.key.gsub(/\.(avi|mpeg|mov|mkv|ogv|webm)$/, '') + '.srt' sub = client.head container, sub_object sub_file = "/tmp/#{SecureRandom.hex}" client.download container, sub_object, :output => sub_file rescue => e Log.error "Error downloading subtitles, ignoring." end end $stderr.reopen('/dev/null', 'w') pipe = IO.popen(player_command(sub_file), 'w') begin cb = Proc.new do |total, bytes, segment| pipe.write segment if bytes > 0 end Log.info "#{set_color 'Playing', :bold} #{to_play.key}" r = client.stream container, to_play.key, :progress_callback => cb Log.debug "Video finished streaming" rescue => e Log.debug "Closing pipe" prettify_backtrace e pipe.close unless pipe.closed? Log.info set_color "\nAdios!", :bold end end |
#configs ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/cifrado/cli/configs.rb', line 10 def configs cdir = Cifrado::Config.instance.config_dir current = "#{cdir}/cifradorc" if [:current] if File.exist?(current) Log.info conceal_password(File.read("#{cdir}/cifradorc")) return 'cifradorc' else raise 'No configuration available.' end end configs = Dir["#{cdir}/cifradorc.*"].map do |c| File.basename(c).gsub('cifradorc.', '') end selected = [:print] if selected and configs.include?(selected) Log.info conceal_password(File.read("#{cdir}/cifradorc.#{selected}")) return selected else raise "Config #{selected} not available." if selected end configs.each { |c| Log.info(c) if c !~ /bak\.\d+/ } configs end |
#delete(container, object = nil) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/cifrado/cli/delete.rb', line 4 def delete(container, object = nil) client = client_instance if object Log.info "Deleting file #{object}..." deleted = false begin client.service.delete_object container, object deleted = true rescue Fog::Storage::OpenStack::NotFound Log.debug 'Trying to find hashed object name' file_hash = (Digest::SHA2.new << object).to_s deleted = client.service.delete_object(container, file_hash) rescue nil end if deleted Log.info "File #{object} deleted" else Log.error "File #{object} not found" end else Log.info "Deleting container '#{container}'..." dir = client.service.directories.get(container) if dir dir.files.each do |f| Log.info "Deleting file #{f.key}..." f.destroy end dir.destroy Log.info "Container #{container} deleted" end end end |
#download(container, object = nil) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/cifrado/cli/download.rb', line 9 def download(container, object = nil) client = client_instance downloaded = [] files = [] if object files << object else Log.info "Downloading files from container #{container}" dir = client.service.directories.get(container) files = dir.files if dir end pb = .new 1, 1, :style => [:progressbar] files.each do |f| obj = f.is_a?(String) ? f : f.key if !f.is_a?(String) and f.[:encrypted_name] fname = decrypt_filename f.[:encrypted_name], @config[:password] + @config[:secure_random] Log.info "Downloading file #{fname}" else Log.info "Downloading file #{obj}" end if client.file_available?(container, obj) r = client.download container, obj, :decrypt => [:decrypt], :passphrase => [:passphrase], :output => [:output], :progress_callback => pb.block, :bwlimit => bwlimit downloaded << obj else Log.debug 'Trying to find hashed object name' file_hash = (Digest::SHA2.new << obj).to_s r = client.download container, file_hash, :decrypt => [:decrypt], :passphrase => [:passphrase], :output => [:output], :progress_callback => pb.block, :bwlimit => bwlimit downloaded << file_hash if r.status == 200 end end Log.warn "No files were downloaded." if downloaded.empty? downloaded end |
#jukebox(container) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/cifrado/cli/jukebox.rb', line 7 def jukebox(container) client = client_instance dir = client.service.directories.get container unless dir raise "Container #{container} not found." end songs = dir.files last_exit = Time.now.to_f Log.info Log.info set_color "Cifrado Jukebox", :bold Log.info "---------------" Log.info Log.info set_color("Ctrl-C once", :bold)+ " -> next song" Log.info set_color("Ctrl-C twice", :bold)+ " -> quit" Log.info $stderr.reopen('/dev/null', 'w') pipe = IO.popen(player_command, 'w') songs.shuffle.each do |song| if [:match] and song.key !~ /#{options[:match]}/i next end begin cb = Proc.new do |total, bytes, segment| pipe.write segment if bytes > 0 end unless (song.content_type =~ /ogg|mp3/) or \ song.key =~ /(mp3|wav|ogg)$/ next end Log.info "#{set_color 'Playing', :bold} song" Log.info " * #{song.key}" r = client.stream container, song.key, :progress_callback => cb Log.debug "Song finished streaming" rescue Timeout::Error, Errno::EPIPE, Interrupt => e Log.debug "Closing pipe" prettify_backtrace e pipe.close unless pipe.closed? Log.debug "Opening new pipe" pipe = IO.popen(player_command, 'w') if Time.now.to_f - last_exit < 1 Log.info set_color "\nAdios!", :bold return else last_exit = Time.now.to_f Log.info 'Next song...' end end end ensure if pipe and !pipe.closed? Log.debug "Closing pipe, killing mplayer" Process.kill 'SIGKILL', pipe.pid pipe.close end end |
#list(container = nil) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/cifrado/cli/list.rb', line 10 def list(container = nil) client = client_instance list = [] if container dir = client.service.directories.get container if dir Log.info "Listing objects in '#{container}'" files = dir.files files.each do |f| fname = f.key unless [:decrypt_filenames] list << fname Log.info fname next end # Skip segments next if fname =~ /\/segments\/\d+\.\d{2}\/\d+\/\d+/ and \ not [:list_segments] # Raises exception if the object is a # manifest but there are no segments available begin = f. rescue Fog::Storage::OpenStack::NotFound Log.warn "The file #{fname} is an object manifest, but there are no segments" Log.warn "available. I won't be able to decrypt the filename." Log.info fname list << fname next end if [:encrypted_name] fname = decrypt_filename [:encrypted_name], @config[:password] + @config[:secure_random] Log.info "#{fname.ljust(55)} #{set_color("[encrypted]",:red, :bold)}" Log.info " hash: #{f.key}" if [:display_hash] else Log.info fname.ljust(55) end list << fname end list else raise "Container '#{container}' not found" end else Log.info "Listing containers" directories = client.service.directories directories = directories.map { |d| Log.info d.key; d.key } directories end end |
#post(container, description = '') ⇒ Object
4 5 6 7 8 |
# File 'lib/cifrado/cli/post.rb', line 4 def post(container, description = '') client = client_instance client.service.directories.create :key => container, :description => description end |
#set_acl(container, object = nil) ⇒ Object
5 6 7 8 |
# File 'lib/cifrado/cli/set_acl.rb', line 5 def set_acl(container, object = nil) client = client_instance client.set_acl [:acl], container end |
#setup ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/cifrado/cli/setup.rb', line 4 def setup config_instance = Cifrado::Config.instance config_file = File.join(config_instance.config_dir, 'cifradorc') unless File.directory?(config_instance.config_dir) FileUtils.mkdir_p config_instance.config_dir end if File.exist?(config_file) Log.warn "Config file #{set_color config_file, :bold} already exist." Log.warn "IMPORTANT: Make sure you backup the current config" Log.warn "before saving a new configuration." unless yes? "Continue?" return end config = YAML.load_file(config_file) else config = {} end puts "Running cifrado setup..." puts "Please provide OpenStack/Rackspace/HPCloud credentials." puts puts "Cifrado can save these settings in #{config_file}" puts "for later use." puts "The settings (password included) are saved unencrypted." puts config[:username] = ask(set_color('Username:', :bold)) system 'stty -echo' config[:password] = ask(set_color 'Password:', :bold) system 'stty echo' puts config[:auth_url] = ask(set_color 'Auth URL:', :bold) if config[:auth_url] !~ /rackspacecloud\.com/ config[:tenant] = ask(set_color('Tenant:', :bold)) end if !config[:secure_random] # shit happens if RUBY_VERSION >= '1.9' config[:secure_random] = SecureRandom.hex.encode('UTF-8') else config[:secure_random] = SecureRandom.hex end end if yes? "Do you want to save these settings? (y/n) " if File.exist?(config_file) backup = "#{config_file}.bak.#{Time.now.to_i}" FileUtils.cp config_file, backup Log.info "Saving backup file to #{backup}." end File.open(config_file, 'w') do |f| f.puts config.to_yaml f.chmod 0600 end @settings_saved = true Log.info "Saved!" end Log.debug "Setup done" config end |
#stat(container = nil, object = nil) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/cifrado/cli/stat.rb', line 4 def stat(container = nil, object = nil) client = client_instance creds = client.service.credentials mgmt_url = creds[:server_management_url] reject_headers = ['Accept-Ranges', 'X-Trans-Id'] unless container and object reject_headers << 'Content-Length' end reject_headers << 'Content-Type' unless object object = clean_object_name(object) if object headers = client.head(container, object) if headers puts "Account:".ljust(30) + File.basename(URI.parse(mgmt_url).path) headers.sort.each do |k, v| next if reject_headers.include?(k) if k == 'X-Timestamp' puts "#{(k + ":").ljust(30)}#{v} (#{unix_time(v)})" elsif k == 'X-Account-Bytes-Used' or k == 'Content-Length' puts "#{(k + ":").ljust(30)}#{v} (#{humanize_bytes(v)})" elsif k == 'X-Object-Meta-Encrypted-Name' puts "#{(k + ":").ljust(30)}#{v}" else puts "#{(k + ":").ljust(30)}#{v}" end end else if object raise "Object not found." else raise "Container not found." end end headers end |
#upload(container, *args) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/cifrado/cli/upload.rb', line 28 def upload(container, *args) if args.empty? help 'upload' raise "No files specified" end client = client_instance uploaded = [] args.each do |file| unless file and File.exist?(file) raise "File '#{file}' does not exist" end if File.directory?(file) files = Dir["#{file}/**/*"].reject { |f| File.directory?(f) } else files = [file] end files.each do |f| begin if [:segments] uploaded << split_and_upload(client, container, f) else headers = client.head container, clean_object_name(f) if headers if headers['Etag'] == Digest::MD5.file(f).to_s if [:force] Log.warn "File #{f} already uploaded and MD5 matches." Log.warn "Since --force was used, uploading it again." uploaded << upload_single(client, container, f) else Log.warn "File #{f} already uploaded and MD5 matches, skipping." end else Log.warn "File #{f} already uploaded, but it has changed." if [:force] Log.warn "Overwriting it as requested (--force)." uploaded << upload_single(client, container, f) else Log.warn "Since --force was not used, skipping it." end end else uploaded << upload_single(client, container, f) end end rescue Errno::ENOENT => e Log.error "Error uploading #{f}: " + e. end end end uploaded.flatten end |
#version ⇒ Object
4 5 6 |
# File 'lib/cifrado/cli/version.rb', line 4 def version Log.info Cifrado::VERSION end |