droxi 0.2.0 → 0.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd104f683fa09123fc4146c2536d47c440139454
4
- data.tar.gz: be57a75ccca1e2c18cca4e9e71df753b5df2f5d7
3
+ metadata.gz: 6e2082eebfa7309caf39ae23503dacebd697b296
4
+ data.tar.gz: df6667fdb18de0438a79c11f990589412a67dae5
5
5
  SHA512:
6
- metadata.gz: 45416d90dec9c6ea116b7c360efcdd0b336e5d6b7933cba981173a9d7337f0bac89798f5b8db13332c77e79da385f4b77e1c334c9410892303051f229e8a61ee
7
- data.tar.gz: d7c3403cf8cdd2684fb5f0f051473802792a9bb1680b28cc5447d1537df63a61befd0b09744854752bc6e1ac1092b725d455211458d298c423ea398f9fc72ede
6
+ metadata.gz: 58ac779ee0ded7200528cc15301da40c6485f3c63fc2cf98ae7282743d31d7e27cbe9c3fedaaabbff5ae6e466f965521ff3a85f506ba1a55c36810ea95da1837
7
+ data.tar.gz: c4c44cb264cd3e9ccc046b50535c93e2451f0363fab1ec7beef8947bf6dc4f910d64f330d871edb2f7be8d355ff58a37c42819b6b78a71d838d0b141cafaade8
data/droxi.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'droxi'
3
3
  s.version = IO.read('lib/droxi.rb')[/VERSION = '(.+)'/, 1]
4
- s.date = '2014-06-09'
4
+ s.date = '2014-09-01'
5
5
  s.summary = 'ftp-like command-line interface to Dropbox'
6
6
  s.description = "A command-line Dropbox interface inspired by GNU \
7
7
  coreutils, GNU ftp, and lftp. Features include smart tab \
@@ -39,7 +39,7 @@ module Commands
39
39
  # If the index is out of range, return the type of the final argument. If
40
40
  # the +Command+ takes no arguments, return +nil+.
41
41
  def type_of_arg(index)
42
- args = @usage.split.drop(1).reject { |arg| arg.include?('-') }
42
+ args = @usage.gsub(/\[-.+?\]/, '').split.drop(1)
43
43
  return nil if args.empty?
44
44
  index = [index, args.size - 1].min
45
45
  args[index].tr('[].', '')
@@ -51,7 +51,7 @@ module Commands
51
51
  # command, +false+ otherwise.
52
52
  def num_args_ok?(num_args)
53
53
  args = @usage.split.drop(1)
54
- min_args = args.reject { |arg| arg.start_with?('[') }.size
54
+ min_args = args.reject { |arg| arg[/[\[\]]/] }.size
55
55
  max_args = if args.any? { |arg| arg.end_with?('...') }
56
56
  num_args
57
57
  else
@@ -66,7 +66,7 @@ module Commands
66
66
  'cat REMOTE_FILE...',
67
67
  'Print the concatenated contents of remote files.',
68
68
  lambda do |client, state, args|
69
- extract_flags('cat', args, '')
69
+ extract_flags(CAT.usage, args, {})
70
70
  state.expand_patterns(args).each do |path|
71
71
  if path.is_a?(GlobError)
72
72
  warn "cat: #{path}: no such file or directory"
@@ -85,7 +85,7 @@ module Commands
85
85
  that directory. With - as the argument, changes to the previous working \
86
86
  directory.",
87
87
  lambda do |_client, state, args|
88
- extract_flags('cd', args, '')
88
+ extract_flags(CD.usage, args, {})
89
89
  case
90
90
  when args.empty? then state.pwd = '/'
91
91
  when args.first == '-' then state.pwd = state.oldpwd
@@ -109,7 +109,7 @@ module Commands
109
109
  that directory. Will refuse to overwrite existing files unless invoked \
110
110
  with the -f option.",
111
111
  lambda do |client, state, args|
112
- cp_mv(client, state, args, 'cp')
112
+ cp_mv(client, state, args, 'cp', CP.usage)
113
113
  end
114
114
  )
115
115
 
@@ -140,7 +140,7 @@ module Commands
140
140
  'exit',
141
141
  'Exit the program.',
142
142
  lambda do |_client, state, args|
143
- extract_flags('exit', args, '')
143
+ extract_flags(EXIT.usage, args, {})
144
144
  state.exit_requested = true
145
145
  end
146
146
  )
@@ -152,7 +152,7 @@ module Commands
152
152
  arguments, clear the entire cache. If given directories as arguments, \
153
153
  (recursively) clear the cache of those directories only.",
154
154
  lambda do |_client, state, args|
155
- extract_flags('forget', args, '')
155
+ extract_flags(FORGET.usage, args, {})
156
156
  if args.empty?
157
157
  state.cache.clear
158
158
  else
@@ -170,7 +170,8 @@ module Commands
170
170
  local working directory. Will refuse to overwrite existing files unless \
171
171
  invoked with the -f option.",
172
172
  lambda do |client, state, args|
173
- flags = extract_flags('get', args, '-f')
173
+ flags = extract_flags(GET.usage, args, '-f' => 0)
174
+
174
175
  state.expand_patterns(args).each do |path|
175
176
  if path.is_a?(GlobError)
176
177
  warn "get: #{path}: no such file or directory"
@@ -196,7 +197,7 @@ module Commands
196
197
  "Print usage and help information about a command. If no command is \
197
198
  given, print a list of commands instead.",
198
199
  lambda do |_client, _state, args|
199
- extract_flags('help', args, '')
200
+ extract_flags(HELP.usage, args, {})
200
201
  if args.empty?
201
202
  Text.table(NAMES).each { |line| puts line }
202
203
  else
@@ -219,7 +220,7 @@ module Commands
219
220
  a previous revision using the 'restore' command and a revision ID given \
220
221
  by this command.",
221
222
  lambda do |client, state, args|
222
- extract_flags('history', args, '')
223
+ extract_flags(HISTORY.usage, args, {})
223
224
  path = state.resolve_path(args.first)
224
225
  if !state.metadata(path) || state.directory?(path)
225
226
  warn "history: #{args.first}: no such file"
@@ -246,7 +247,7 @@ module Commands
246
247
  that directory. With - as the argument, changes to the previous working \
247
248
  directory.",
248
249
  lambda do |_client, state, args|
249
- extract_flags('lcd', args, '')
250
+ extract_flags(LCD.usage, args, {})
250
251
  path = case
251
252
  when args.empty? then File.expand_path('~')
252
253
  when args.first == '-' then state.local_oldpwd
@@ -276,7 +277,7 @@ module Commands
276
277
  as arguments, list the files. If the -l option is given, display \
277
278
  information about the files.",
278
279
  lambda do |_client, state, args|
279
- long = extract_flags('ls', args, '-l').include?('-l')
280
+ long = extract_flags(LS.usage, args, '-l' => 0).include?('-l')
280
281
 
281
282
  files, dirs = [], []
282
283
  state.expand_patterns(args, true).each do |path|
@@ -311,7 +312,7 @@ module Commands
311
312
  "Create Dropbox links to publicly share remote files. The links are \
312
313
  time-limited and link directly to the files themselves.",
313
314
  lambda do |client, state, args|
314
- extract_flags('media', args, '')
315
+ extract_flags(MEDIA.usage, args, {})
315
316
  state.expand_patterns(args).each do |path|
316
317
  if path.is_a?(GlobError)
317
318
  warn "media: #{path}: no such file or directory"
@@ -330,7 +331,7 @@ module Commands
330
331
  'mkdir REMOTE_DIR...',
331
332
  'Create remote directories.',
332
333
  lambda do |client, state, args|
333
- extract_flags('mkdir', args, '')
334
+ extract_flags(MKDIR.usage, args, {})
334
335
  args.each do |arg|
335
336
  try_and_handle(DropboxError) do
336
337
  path = state.resolve_path(arg)
@@ -350,19 +351,33 @@ module Commands
350
351
  that directory. Will refuse to overwrite existing files unless invoked \
351
352
  with the -f option.",
352
353
  lambda do |client, state, args|
353
- cp_mv(client, state, args, 'mv')
354
+ cp_mv(client, state, args, 'mv', MV.usage)
354
355
  end
355
356
  )
356
357
 
357
358
  # Upload a local file.
358
359
  PUT = Command.new(
359
- 'put [-f] LOCAL_FILE...',
360
+ 'put [-f] [-O REMOTE_DIR] LOCAL_FILE...',
360
361
  "Upload local files to the remote working directory. If a remote file of \
361
362
  the same name already exists, Dropbox will rename the upload unless the \
362
363
  the -f option is given, in which case the remote file will be \
363
- overwritten.",
364
+ overwritten. If the -O option is given, the files will be uploaded to \
365
+ the given directory instead of the current directory.",
364
366
  lambda do |client, state, args|
365
- flags = extract_flags('put', args, '-f')
367
+ flags = extract_flags(PUT.usage, args, '-f' => 0, '-O' => 1)
368
+
369
+ dest_index = flags.find_index('-O')
370
+ dest_path = nil
371
+ unless dest_index.nil?
372
+ dest_path = flags[dest_index + 1]
373
+ if state.directory?(dest_path)
374
+ state.pwd = state.resolve_path(dest_path)
375
+ else
376
+ warn "put: #{dest_path}: no such directory"
377
+ return
378
+ end
379
+ end
380
+
366
381
  args.each do |arg|
367
382
  to_path = state.resolve_path(File.basename(arg))
368
383
 
@@ -378,6 +393,8 @@ module Commands
378
393
  end
379
394
  end
380
395
  end
396
+
397
+ state.pwd = state.oldpwd unless dest_path.nil?
381
398
  end
382
399
  )
383
400
 
@@ -387,7 +404,7 @@ module Commands
387
404
  "Restore a remote file to a previous version. Use the 'history' command \
388
405
  to get a list of IDs for previous revisions of the file.",
389
406
  lambda do |client, state, args|
390
- extract_flags('restore', args, '')
407
+ extract_flags(RESTORE.usage, args, {})
391
408
  path = state.resolve_path(args.first)
392
409
  if !state.metadata(path) || state.directory?(path)
393
410
  warn "restore: #{args.first}: no such file"
@@ -405,7 +422,7 @@ module Commands
405
422
  "Remove each specified remote file. If the -r option is given, will \
406
423
  also remove directories recursively.",
407
424
  lambda do |client, state, args|
408
- flags = extract_flags('rm', args, '-r')
425
+ flags = extract_flags(RM.usage, args, '-r' => 0)
409
426
  state.expand_patterns(args).each do |path|
410
427
  if path.is_a?(GlobError)
411
428
  warn "rm: #{path}: no such file or directory"
@@ -429,7 +446,7 @@ module Commands
429
446
  'rmdir REMOTE_DIR...',
430
447
  'Remove each specified empty remote directory.',
431
448
  lambda do |client, state, args|
432
- extract_flags('rmdir', args, '')
449
+ extract_flags(RMDIR.usage, args, {})
433
450
  state.expand_patterns(args).each do |path|
434
451
  if path.is_a?(GlobError)
435
452
  warn "rmdir: #{path}: no such file or directory"
@@ -459,7 +476,7 @@ module Commands
459
476
  "List remote files in a directory or its subdirectories with names that \
460
477
  contain all given substrings.",
461
478
  lambda do |client, state, args|
462
- extract_flags('search', args, '')
479
+ extract_flags(SEARCH.usage, args, {})
463
480
  path = state.resolve_path(args.first)
464
481
  unless state.directory?(path)
465
482
  warn "search: #{args.first}: no such directory"
@@ -480,7 +497,7 @@ module Commands
480
497
  this method are set to expire far enough in the future so that \
481
498
  expiration is effectively not an issue.",
482
499
  lambda do |client, state, args|
483
- extract_flags('share', args, '')
500
+ extract_flags(SHARE.usage, args, {})
484
501
  state.expand_patterns(args).each do |path|
485
502
  if path.is_a?(GlobError)
486
503
  warn "share: #{path}: no such file or directory"
@@ -602,8 +619,8 @@ module Commands
602
619
  end
603
620
 
604
621
  # Execute a 'mv' or 'cp' operation depending on arguments given.
605
- def self.cp_mv(client, state, args, cmd)
606
- flags = extract_flags(cmd, args, '-f')
622
+ def self.cp_mv(client, state, args, cmd, usage)
623
+ flags = extract_flags(usage, args, '-f' => 0)
607
624
  sources = expand(state, args.take(args.size - 1), true, true, cmd)
608
625
  method = (cmd == 'cp') ? :file_copy : :file_move
609
626
  dest = state.resolve_path(args.last)
@@ -635,17 +652,44 @@ module Commands
635
652
  (state.pwd = File.dirname(state.pwd)) until state.metadata(state.pwd)
636
653
  end
637
654
 
655
+ # def self.extract_flags(@usage, cmd, args, valid_flags)
656
+ # tokens = args.take_while { |s| s[/^-\w+$/] }
657
+ # args.shift(tokens.size)
658
+
659
+ # # Process compound flags like -rf into -r, -f.
660
+ # flags = tokens.join.chars.uniq.drop(1).map { |c| "-#{c}" }
661
+ # invalid_flags = flags.reject { |f| valid_flags[f[1]] }
662
+ # invalid_flags.each { |f| warn "#{cmd}: #{f}: invalid option" }
663
+ # flags
664
+ # end
665
+
638
666
  # Removes flags (e.g. -f) from the +Array+ and returns an +Array+ of the
639
667
  # removed flags. Prints warnings if the flags are not in the given +String+
640
668
  # of valid flags (e.g. '-rf').
641
- def self.extract_flags(cmd, args, valid_flags)
642
- tokens = args.take_while { |s| s[/^-\w+$/] }
643
- args.shift(tokens.size)
644
-
645
- # Process compound flags like -rf into -r, -f.
646
- flags = tokens.join.chars.uniq.drop(1).map { |c| "-#{c}" }
647
- invalid_flags = flags.reject { |f| valid_flags[f[1]] }
648
- invalid_flags.each { |f| warn "#{cmd}: #{f}: invalid option" }
649
- flags
669
+ def self.extract_flags(usage, args, flags)
670
+ extracted, index = [], 0
671
+ while index < args.size
672
+ arg = args[index]
673
+ extracted_flags =
674
+ arg[/^-\w/] ? extract_flag(usage, args, flags, arg, index) : nil
675
+ extracted += extracted_flags unless extracted_flags.nil?
676
+ index += 1 if extracted_flags.nil? || extracted_flags.empty?
677
+ end
678
+ args.delete_if { |a| a[/^-\w/] }
679
+ extracted
680
+ end
681
+
682
+ # Removes a flag and its arugments from the +Array+ and returns an +Array+ of
683
+ # the flag and its arguments. Prints warnings if the given flag is invalid.
684
+ def self.extract_flag(usage, args, flags, arg, index)
685
+ num_args = flags[arg]
686
+ if num_args.nil?
687
+ fail UsageError, usage
688
+ else
689
+ if index + num_args < args.size
690
+ return (num_args + 1).times.map { args.delete_at(index) }
691
+ end
692
+ fail UsageError, usage
693
+ end
650
694
  end
651
695
  end
data/lib/droxi.rb CHANGED
@@ -10,7 +10,7 @@ require_relative 'droxi/text'
10
10
  # Command-line Dropbox client module.
11
11
  module Droxi
12
12
  # Version number of the program.
13
- VERSION = '0.2.0'
13
+ VERSION = '0.2.1'
14
14
 
15
15
  # Message to display when invoked with the --help option.
16
16
  HELP_TEXT =
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: droxi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Mulcahy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-09 00:00:00.000000000 Z
11
+ date: 2014-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dropbox-sdk