lib/mpw/cli.rb in mpw-4.1.1 vs lib/mpw/cli.rb in mpw-4.2.0

- old
+ new

@@ -26,40 +26,39 @@ require 'mpw/item' require 'mpw/mpw' module MPW class Cli - # Constructor - # @args: config -> the config + # @param config [Config] def initialize(config) @config = config end # Change a parameter int the config after init - # @args: options -> param to change + # @param options [Hash] param to change def set_config(options) @config.setup(options) puts I18n.t('form.set_config.valid').to_s.green rescue => e puts "#{I18n.t('display.error')} #15: #{e}".red exit 2 end # Change the wallet path - # @args: path -> the new path + # @param path [String] new path def set_wallet_path(path) @config.set_wallet_path(path, @wallet) puts I18n.t('form.set_wallet_path.valid').to_s.green rescue => e puts "#{I18n.t('display.error')} #19: #{e}".red exit 2 end # Create a new config file - # @args: options -> set param + # @param options [Hash] def setup(options) options[:lang] = options[:lang] || Locale::Tag.parse(ENV['LANG']).to_simple.to_s[0..1] I18n.locale = options[:lang].to_sym @@ -72,11 +71,11 @@ puts "#{I18n.t('display.error')} #8: #{e}".red exit 2 end # Setup a new GPG key - # @args: gpg_key -> the key name + # @param gpg_key [String] gpg key name def setup_gpg_key(gpg_key) return if @config.check_gpg_key? password = ask(I18n.t('form.setup_gpg_key.password')) { |q| q.echo = false } confirm = ask(I18n.t('form.setup_gpg_key.confirm_password')) { |q| q.echo = false } @@ -104,11 +103,11 @@ def list_config config = { 'lang' => @config.lang, 'gpg_key' => @config.gpg_key, 'default_wallet' => @config.default_wallet, - 'config_dir' => @config.config_dir, + 'wallet_dir' => @config.wallet_dir, 'pinmode' => @config.pinmode, 'gpg_exe' => @config.gpg_exe } @config.wallet_paths.each { |k, v| config["path_wallet_#{k}"] = "#{v}/#{k}.mpw" } @@ -125,24 +124,32 @@ exit 2 end # Request the GPG password and decrypt the file def decrypt - unless defined?(@mpw) - @password = ask(I18n.t('display.gpg_password')) { |q| q.echo = false } - @mpw = MPW.new(@config.gpg_key, @wallet_file, @password, @config.gpg_exe, @config.pinmode) - end + if defined?(@mpw) + @mpw.read_data + else + begin + @mpw = MPW.new(@config.gpg_key, @wallet_file, nil, @config.gpg_exe, @config.pinmode) - @mpw.read_data + @mpw.read_data + rescue + @password = ask(I18n.t('display.gpg_password')) { |q| q.echo = false } + @mpw = MPW.new(@config.gpg_key, @wallet_file, @password, @config.gpg_exe, @config.pinmode) + + @mpw.read_data + end + end rescue => e puts "#{I18n.t('display.error')} #11: #{e}".red exit 2 end # Format list on a table - # @args: title -> the name of table - # list -> array or hash + # @param title [String] name of table + # @param list an array or hash def table_list(title, list) length = { k: 0, v: 0 } if list.is_a?(Array) i = 0 @@ -170,28 +177,31 @@ print "\n" end # Format items on a table - # @args: items -> an aray items + # @param items [Array] def table_items(items = []) group = '.' i = 1 length_total = 10 data = { id: { length: 3, color: 'cyan' }, host: { length: 9, color: 'yellow' }, user: { length: 7, color: 'green' }, - protocol: { length: 9, color: 'white' }, - port: { length: 5, color: 'white' }, otp: { length: 4, color: 'white' }, comment: { length: 14, color: 'magenta' } } items.each do |item| data.each do |k, v| - next if k == :id || k == :otp - - v[:length] = item.send(k.to_s).to_s.length + 3 if item.send(k.to_s).to_s.length >= v[:length] + case k + when :id, :otp + next + when :host + v[:length] = item.url.length + 3 if item.url.length >= v[:length] + else + v[:length] = item.send(k.to_s).to_s.length + 3 if item.send(k.to_s).to_s.length >= v[:length] + end end end data[:id][:length] = items.length.to_s.length + 2 if items.length.to_s.length > data[:id][:length] data.each_value { |v| length_total += v[:length] } @@ -230,31 +240,37 @@ print " #{i}".send(data[:id][:color]) (data[:id][:length] - i.to_s.length).times { print ' ' } data.each do |k, v| next if k == :id - if k == :otp - print '| ' + print '| ' + + case k + when :otp item.otp ? (print ' X ') : 4.times { print ' ' } - next - end + when :host + print "#{item.protocol}://".light_black if item.protocol + print item.host.send(v[:color]) + print ":#{item.port}".light_black if item.port + (v[:length] - item.url.to_s.length).times { print ' ' } - print '| ' - print item.send(k.to_s).to_s.send(v[:color]) - (v[:length] - item.send(k.to_s).to_s.length).times { print ' ' } + else + print item.send(k.to_s).to_s.send(v[:color]) + (v[:length] - item.send(k.to_s).to_s.length).times { print ' ' } + end end print "\n" i += 1 end print "\n" end # Display the query's result - # @args: options -> the option to search + # @param options [Hash] the options to search def list(**options) result = @mpw.list(options) if result.empty? puts I18n.t('display.nothing') @@ -262,24 +278,24 @@ table_items(result) end end # Get an item when multiple choice - # @args: items -> array of items - # @rtrn: item + # @param items [Array] list of items + # @return [Item] an item def get_item(items) return items[0] if items.length == 1 items.sort! { |a, b| a.group.to_s.downcase <=> b.group.to_s.downcase } choice = ask(I18n.t('form.select')).to_i choice >= 1 && choice <= items.length ? items[choice - 1] : nil end # Copy in clipboard the login and password - # @args: item -> the item - # clipboard -> enable clipboard + # @param item [Item] + # @param clipboard [Boolean] enable clipboard def clipboard(item, clipboard = true) # Security: force quit after 90s Thread.new do sleep 90 exit @@ -290,10 +306,18 @@ case choice when 'q', 'quit' break + when 'u', 'url' + if clipboard + Clipboard.copy(item.url) + puts I18n.t('form.clipboard.url').green + else + puts item.url + end + when 'l', 'login' if clipboard Clipboard.copy(item.user) puts I18n.t('form.clipboard.login').green else @@ -322,10 +346,11 @@ end puts I18n.t('form.clipboard.otp', time: @mpw.get_otp_remaining_time).yellow else puts "----- #{I18n.t('form.clipboard.help.name')} -----".cyan + puts I18n.t('form.clipboard.help.url') puts I18n.t('form.clipboard.help.login') puts I18n.t('form.clipboard.help.password') puts I18n.t('form.clipboard.help.otp_code') puts I18n.t('form.clipboard.help.quit') next @@ -348,11 +373,11 @@ table_list('wallets', wallets) end # Display the wallet - # @args: wallet -> the wallet name + # @param wallet [String] wallet name def get_wallet(wallet = nil) @wallet = if wallet.to_s.empty? wallets = Dir.glob("#{@config.wallet_dir}/*.mpw") if wallets.length == 1 @@ -373,36 +398,36 @@ "#{@config.wallet_dir}/#{@wallet}.mpw" end end # Add a new public key - # args: key -> the key name or key file to add + # @param key [String] key name or key file to add def add_key(key) @mpw.add_key(key) @mpw.write_data puts I18n.t('form.add_key.valid').to_s.green rescue => e puts "#{I18n.t('display.error')} #13: #{e}".red end # Add new public key - # args: key -> the key name to delete + # @param key [String] key name to delete def delete_key(key) @mpw.delete_key(key) @mpw.write_data puts I18n.t('form.delete_key.valid').to_s.green rescue => e puts "#{I18n.t('display.error')} #15: #{e}".red end # Text editor interface - # @args: template -> template name - # item -> the item to edit - # password -> disable field password - # @rtrn: a hash with the value for an item + # @param template_name [String] template name + # @param item [Item] the item to edit + # @param password [Boolean] disable field password + # @return [Hash] the values for an item def text_editor(template_name, password = false, item = nil, **options) editor = ENV['EDITOR'] || 'nano' opts = {} template_file = "#{File.expand_path('../../../templates', __FILE__)}/#{template_name}.erb" template = ERB.new(IO.read(template_file)) @@ -427,13 +452,13 @@ options end # Form to add a new item - # @args: password -> generate a random password - # text_editor -> enable text editor mode - # values -> hash with multiples value to set the item + # @param password [Boolean] generate a random password + # @param text_editor [Boolean] enable text editor mode + # @param values [Hash] multiples value to set the item def add(password = false, text_editor = false, **values) options = text_editor('add_form', password, nil, values) if text_editor item = Item.new(options) options[:password] = MPW.password(@config.password) if password @@ -446,19 +471,19 @@ rescue => e puts "#{I18n.t('display.error')} #13: #{e}".red end # Update an item - # @args: password -> generate a random password - # text_editor -> enable text editor mode - # options -> the option to search - # values -> hash with multiples value to set the item + # @param password [Boolean] generate a random password + # @param text_editor [Boolean] enable text editor mode + # @param options [Hash] the options to search + # @param values [Hash] multiples value to set the item def update(password = false, text_editor = false, options = {}, **values) items = @mpw.list(options) if items.empty? - puts "#{I18n.t('display.warning')}: #{I18n.t('warning.select')}".yellow + puts I18n.t('display.nothing') else table_items(items) if items.length > 1 item = get_item(items) values = text_editor('update_form', password, item, values) if text_editor @@ -474,16 +499,16 @@ rescue => e puts "#{I18n.t('display.error')} #14: #{e}".red end # Remove an item - # @args: options -> the option to search + # @param options [Hash] the options to search def delete(**options) items = @mpw.list(options) if items.empty? - puts "#{I18n.t('display.warning')}: #{I18n.t('warning.select')}".yellow + puts I18n.t('display.nothing') else table_items(items) item = get_item(items) confirm = ask("#{I18n.t('form.delete_item.ask')} (y/N) ").to_s @@ -498,12 +523,12 @@ rescue => e puts "#{I18n.t('display.error')} #16: #{e}".red end # Copy a password, otp, login - # @args: clipboard -> enable clipboard - # options -> the option to search + # @param clipboard [Boolean] enable clipboard + # @param options [Hash] the options to search def copy(clipboard = true, **options) items = @mpw.list(options) if items.empty? puts I18n.t('display.nothing') @@ -515,13 +540,13 @@ end rescue => e puts "#{I18n.t('display.error')} #14: #{e}".red end - # Export the items in a CSV file - # @args: file -> the destination file - # options -> option to search + # Export the items in an yaml file + # @param file [String] the path of destination file + # @param options [Hash] options to search def export(file, options) file = 'export-mpw.yml' if file.to_s.empty? items = @mpw.list(options) data = {} @@ -547,11 +572,11 @@ puts I18n.t('form.export.valid', file: file).to_s.green rescue => e puts "#{I18n.t('display.error')} #17: #{e}".red end - # Import items from a YAML file - # @args: file -> the import file + # Import items from an yaml file + # @param file [String] path of import file def import(file) raise I18n.t('form.import.file_empty') if file.to_s.empty? raise I18n.t('form.import.file_not_exist') unless File.exist?(file) YAML.load_file(file).each_value do |row|