module Droxi

Command-line Dropbox client module.

Constants

HELP_TEXT

Message to display when invoked with the –help option.

VERSION

Version number of the program.

Public Class Methods

run() click to toggle source

Run the client.

# File lib/droxi.rb, line 32
def self.run
  reenter = ARGV[0] == 'REENTER'
  ARGV.delete_if { |arg| arg == 'REENTER' }
  original_argv = ARGV.dup
  options, args = handle_options
  Settings.init

  client = DropboxClient.new(access_token)
  state = State.new(client, args.empty?, original_argv)
  state.debug_enabled = options[:debug]

  if args.empty?
    run_interactive(client, state, reenter)
  else
    invoke(args, client, state)
  end
rescue DropboxAuthError => error
  warn error
  state.exit_status = 1
  Settings.delete(:access_token)
ensure
  Settings.save
  exit state.exit_status
end

Private Class Methods

access_token() click to toggle source

Return the access token for the user, requesting authorization if no saved token exists.

# File lib/droxi.rb, line 134
def self.access_token
  authorize until Settings.include?(:access_token)
  Settings[:access_token]
end
authorize() click to toggle source

Attempt to authorize the user for app usage.

# File lib/droxi.rb, line 116
def self.authorize
  app_key = '5sufyfrvtro9zp7'
  app_secret = 'h99ihzv86jyypho' # Not so secret, is it?

  flow = DropboxOAuth2FlowNoRedirect.new(app_key, app_secret)

  authorize_url = flow.start
  code = get_auth_code(authorize_url)

  begin
    Settings[:access_token] = flow.finish(code).first
  rescue DropboxError
    puts 'Invalid authorization code.'
  end
end
do_interaction_loop(client, state, info) click to toggle source

Run the main loop of the program, getting user input and executing it as a command until an getting input fails or an exit is requested.

# File lib/droxi.rb, line 186
def self.do_interaction_loop(client, state, info)
  until state.exit_requested
    line = Readline.readline(prompt(info, state), true)
    break unless line
    with_interrupt_handling { Commands.exec(line.chomp, client, state) }
  end
  puts unless line
end
get_auth_code(url) click to toggle source
# File lib/droxi.rb, line 195
def self.get_auth_code(url)
  puts 'Authorize this app to access your Dropbox at: ' + url
  print 'Enter authorization code: '
  code = $stdin.gets
  code ? code.strip! : exit
end
handle_options() click to toggle source

Handles command-line options and returns a Hash of the extracted options, and an Array of the remaining arguments.

# File lib/droxi.rb, line 61
def self.handle_options
  options = { debug: false }

  parser = OptionParser.new do |opts|
    opts.banner = 'Usage: droxi [OPTION ...] [COMMAND [ARGUMENT ...]]'

    opts.separator ''
    HELP_TEXT.each do |text|
      Text.wrap(text).each { |s| opts.separator(s) }
      opts.separator ''
    end
    opts.separator 'Options:'

    opts.on('--debug', 'Enable debug command') { options[:debug] = true }

    opts.on('-f', '--file FILE', String,
            'Specify path of config file') do |path|
      Settings.config_file_path = path
    end

    opts.on('-h', '--help', 'Print help information and exit') do
      puts opts
      exit
    end

    opts.on('--version', 'Print version information and exit') do
      puts "droxi v#{VERSION}"
      exit
    end
  end

  begin
    global_opts = ARGV.take_while { |arg| !Commands::NAMES.include?(arg) }
    num_opts = global_opts.size
    parser.parse!(global_opts)
  rescue OptionParser::ParseError => err
    warn(err)
    exit(1)
  end

  [options, global_opts + ARGV.drop(num_opts)]
end
ignore_not_yet_implemented() { || ... } click to toggle source
# File lib/droxi.rb, line 172
def self.ignore_not_yet_implemented
  yield
rescue NotImplementedError
  nil
end
init_readline(state) click to toggle source
# File lib/droxi.rb, line 164
def self.init_readline(state)
  Readline.completion_proc = proc do
    Complete.complete(Readline.line_buffer, state)
  end

  ignore_not_yet_implemented { Readline.completion_append_character = nil }
end
invoke(args, client, state) click to toggle source

Invokes a single command formed by joining an Array of String args.

# File lib/droxi.rb, line 105
def self.invoke(args, client, state)
  with_interrupt_handling { Commands.exec(join_cmd(args), client, state) }
end
join_cmd(args) click to toggle source

Return a String of joined command-line args, adding backslash escapes for spaces.

# File lib/droxi.rb, line 111
def self.join_cmd(args)
  args.map { |arg| arg.gsub(' ', '\ ') }.join(' ')
end
prompt(info, state) click to toggle source

Return a prompt message reflecting the current state of the application.

# File lib/droxi.rb, line 140
def self.prompt(info, state)
  "\rdroxi #{info['email']}:#{state.pwd}> "
end
run_interactive(client, state, reenter) click to toggle source

Run the client in interactive mode.

# File lib/droxi.rb, line 145
def self.run_interactive(client, state, reenter)
  info = client.account_info
  if reenter
    state.pwd = state.oldpwd
  else
    puts "Logged in as #{info['display_name']} (#{info['email']})"
  end

  init_readline(state)
  with_interrupt_handling { do_interaction_loop(client, state, info) }

  # Set pwd before exiting so that the oldpwd setting is saved to the pwd.
  state.pwd = '/'

  # Set exit status to zero even if the last command had an error, since
  # we're in interactive mode and quitting correctly.
  state.exit_status = 0
end
with_interrupt_handling() { || ... } click to toggle source
# File lib/droxi.rb, line 178
def self.with_interrupt_handling
  yield
rescue Interrupt
  puts
end