Module: Droxi

Defined in:
lib/droxi.rb

Overview

Command-line Dropbox client module.

Constant Summary collapse

VERSION =

Version number of the program.

'0.2.3'
HELP_TEXT =

Message to display when invoked with the –help option.

"If you've installed this program using Rake or the AUR package, you " \
'should also have the man page installed on your system. `man droxi` ' \
"should do the trick. Otherwise--meaning you've probably installed it " \
"as a Ruby gem--you don't, which is a shame. In that case, you can " \
'access the man page at http://jangler.info/man/droxi in HTML form.'

Class Method Summary collapse

Class Method Details

.access_tokenObject

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



81
82
83
84
# File 'lib/droxi.rb', line 81

def self.access_token
  authorize until Settings.include?(:access_token)
  Settings[:access_token]
end

.authorizeObject

Attempt to authorize the user for app usage.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/droxi.rb', line 63

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) ⇒ Object

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.



125
126
127
128
129
130
131
132
# File 'lib/droxi.rb', line 125

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) ⇒ Object



134
135
136
137
138
139
# File 'lib/droxi.rb', line 134

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(args) ⇒ Object

Handles command-line options extracted from an Array and returns an Array of the extracted options.



43
44
45
46
47
48
49
# File 'lib/droxi.rb', line 43

def self.handle_options(args)
  options = args.take_while { |s| s.start_with?('--') }
  puts "droxi v#{VERSION}" if options.include?('--version')
  Text.wrap(HELP_TEXT).each { |s| puts s } if options.include?('--help')
  exit if %w(--help --version).any? { |s| options.include?(s) }
  options
end

.ignore_not_yet_implementedObject



111
112
113
114
115
# File 'lib/droxi.rb', line 111

def self.ignore_not_yet_implemented
  yield
rescue NotImplementedError
  nil
end

.init_readline(state) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/droxi.rb', line 103

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) ⇒ Object

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



52
53
54
# File 'lib/droxi.rb', line 52

def self.invoke(args, client, state)
  with_interrupt_handling { Commands.exec(join_cmd(args), client, state) }
end

.join_cmd(args) ⇒ Object

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



58
59
60
# File 'lib/droxi.rb', line 58

def self.join_cmd(args)
  args.map { |arg| arg.gsub(' ', '\ ') }.join(' ')
end

.prompt(info, state) ⇒ Object

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



87
88
89
# File 'lib/droxi.rb', line 87

def self.prompt(info, state)
  "\rdroxi #{info['email']}:#{state.pwd}> "
end

.run(args) ⇒ Object

Run the client.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/droxi.rb', line 24

def self.run(args)
  client = DropboxClient.new(access_token)
  state = State.new(client)

  options = handle_options(args)
  args.shift(options.size)

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

.run_interactive(client, state) ⇒ Object

Run the client in interactive mode.



92
93
94
95
96
97
98
99
100
101
# File 'lib/droxi.rb', line 92

def self.run_interactive(client, state)
  info = client.
  puts "Logged in as #{info['display_name']} (#{info['email']})"

  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 = '/'
end

.with_interrupt_handlingObject



117
118
119
120
121
# File 'lib/droxi.rb', line 117

def self.with_interrupt_handling
  yield
rescue Interrupt
  puts
end