rb1drv-tools 0.0.0placeholder → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aba9f409761da12f320a4ad92d85b3ddf626a499aa54b8eec82d9019d5512270
4
- data.tar.gz: 769a15590760c653544bcedce72b551d698427ae49c6505cd5e0e54ed3d33746
3
+ metadata.gz: ce495e7400324adf72beecc7e7b9ecc99e2b4be30c7493a5a4c9eed5285d7a07
4
+ data.tar.gz: 885f0b728020e2850f027448e46d87d227d00c8dbae6437c3aabaa399ea534e8
5
5
  SHA512:
6
- metadata.gz: bd026ae0646eee9ecbba3299690f12e6f10df5c41df34fa3e87449b37579ed9194aaf56c04c37b5af518be0f865b41eaceb6d7828f6674c27a489b5a147207d3
7
- data.tar.gz: eebe2ab06800d6fa0aaa990ea6e81f0dfb5a6ef6a8bf1810ee1c23a242c497f9c1312c4520c6daebecc54c99460579bcc94f62aa0d49fade27bd9e4fca359c65
6
+ metadata.gz: 3db17c8b96ba1401ca2672b4dd2abd2b5faa955b158a291400e34879895660ec858f6c6d858ba40bf74959ba28ce668c3e733771806281e2e9bc7fd2bfde3ac1
7
+ data.tar.gz: 5e7bd497cd1f661511f62a8aff8b9ac2bf99483121999977cbc94be68ae3f47f1fd7de94f1e60b78b6454e74d37a9fe01bac17298041ab0acb82fa598dd82603
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.5
4
+ script: bundle exec ruby -I lib lib/rb1drv-tools.rb
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in rb1drv-tools.gemspec
6
+ gemspec
7
+
@@ -0,0 +1,66 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rb1drv-tools (0.1.0)
5
+ rb1drv (~> 0.1)
6
+ tty-progressbar (~> 0)
7
+ tty-prompt (~> 0)
8
+ tty-screen (~> 0)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ equatable (0.5.0)
14
+ excon (0.62.0)
15
+ faraday (0.12.2)
16
+ multipart-post (>= 1.2, < 3)
17
+ hitimes (1.2.6)
18
+ jwt (1.5.6)
19
+ multi_json (1.13.1)
20
+ multi_xml (0.6.0)
21
+ multipart-post (2.0.0)
22
+ necromancer (0.4.0)
23
+ oauth2 (1.4.0)
24
+ faraday (>= 0.8, < 0.13)
25
+ jwt (~> 1.0)
26
+ multi_json (~> 1.3)
27
+ multi_xml (~> 0.5)
28
+ rack (>= 1.2, < 3)
29
+ pastel (0.7.2)
30
+ equatable (~> 0.5.0)
31
+ tty-color (~> 0.4.0)
32
+ rack (2.0.5)
33
+ rake (10.5.0)
34
+ rb1drv (0.1.4)
35
+ excon (~> 0.62)
36
+ oauth2 (~> 1.4)
37
+ timers (4.1.2)
38
+ hitimes
39
+ tty-color (0.4.2)
40
+ tty-cursor (0.5.0)
41
+ tty-progressbar (0.14.0)
42
+ tty-cursor (~> 0.5.0)
43
+ tty-screen (~> 0.6.4)
44
+ tty-prompt (0.16.1)
45
+ necromancer (~> 0.4.0)
46
+ pastel (~> 0.7.0)
47
+ timers (~> 4.0)
48
+ tty-cursor (~> 0.5.0)
49
+ tty-reader (~> 0.3.0)
50
+ tty-reader (0.3.0)
51
+ tty-cursor (~> 0.5.0)
52
+ tty-screen (~> 0.6.4)
53
+ wisper (~> 2.0.0)
54
+ tty-screen (0.6.4)
55
+ wisper (2.0.0)
56
+
57
+ PLATFORMS
58
+ ruby
59
+
60
+ DEPENDENCIES
61
+ bundler (~> 1.16)
62
+ rake (~> 10.0)
63
+ rb1drv-tools!
64
+
65
+ BUNDLED WITH
66
+ 1.16.1
data/README.md CHANGED
@@ -1 +1,23 @@
1
- # Rb1drv-tools
1
+ # Rb1drv-Tools
2
+
3
+ [![Build Status](https://travis-ci.org/msg7086/rb1drv-tools.svg?branch=master)](https://travis-ci.org/msg7086/rb1drv-tools)
4
+
5
+ Rb1drv-tools provides basic file operations on OneDrive.
6
+
7
+ ## Installation
8
+
9
+ Install it yourself as:
10
+
11
+ $ gem install rb1drv-tools --no-ri
12
+
13
+ ## Usage
14
+
15
+ TODO: Write usage instructions here
16
+
17
+ ## Contributing
18
+
19
+ Bug reports and pull requests are welcome on GitHub at https://github.com/msg7086/rb1drv-tools.
20
+
21
+ ## License
22
+
23
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rb1drv/tools"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/1d ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rb1drv-tools'
4
+ include Rb1drvTools
5
+
6
+ logger = ENV['DEBUG'].to_s.empty? ? nil : Logger.new(STDERR)
7
+
8
+ CLI.new('5aa1a4d9-a818-45b2-b28f-dbd6f11cd9fc', 'iwgvHYQV83)(cenTLA082}(', 'https://ruby-1drive.gitlab.io/od/', logger)
@@ -0,0 +1,13 @@
1
+ require "rb1drv-tools/version"
2
+
3
+ module Rb1drvTools
4
+ end
5
+
6
+ require 'tty-prompt'
7
+ require 'tty-progressbar'
8
+
9
+ require 'rb1drv'
10
+ include Rb1drv
11
+ require 'rb1drv-tools/profile'
12
+ require 'rb1drv-tools/utils'
13
+ require 'rb1drv-tools/cli'
@@ -0,0 +1,73 @@
1
+ module Rb1drvTools
2
+ class CLI
3
+ CLI_DELIMITER = '-,-'
4
+ def initialize(*args)
5
+ CLI.set_od(*args)
6
+
7
+ @profiles = Profile.all
8
+ @profile_index = nil
9
+ @profile = nil
10
+
11
+ ARGV << 'help' if ARGV.empty?
12
+
13
+ set_profile
14
+ split_args.each do |args|
15
+ dispatch_command args
16
+ end
17
+ end
18
+
19
+ def set_profile
20
+ if ARGV.first[0] == ':'
21
+ @profile_index = ARGV.shift[1..-1]
22
+ Profile.profile_index = @profile_index
23
+ end
24
+ end
25
+
26
+ def split_args
27
+ argv = ARGV.dup
28
+ @profile_index = argv.shift[1..-1] if argv.first[0] == ':'
29
+ Enumerator.new do |y|
30
+ while delimiter_pos = argv.index(CLI_DELIMITER)
31
+ y << argv[0...delimiter_pos]
32
+ argv = argv[(delimiter_pos+1)..-1]
33
+ end
34
+ y << argv
35
+ end
36
+ end
37
+
38
+ def dispatch_command(args)
39
+ return if args.empty?
40
+ cmd = args.shift
41
+ method = "cmd_#{cmd}"
42
+ unless Command.respond_to?(method)
43
+ puts "Unknown command #{cmd}"
44
+ return
45
+ end
46
+ Command.send(method, args)
47
+ end
48
+
49
+ def self.cwd
50
+ @cwd ||= CLI.od.root
51
+ end
52
+
53
+ def self.cwd=value
54
+ @cwd = value
55
+ end
56
+
57
+ def self.set_od(*args)
58
+ @logger = args[3]
59
+ @od = OneDrive.new(*args)
60
+ end
61
+
62
+ def self.od
63
+ @od
64
+ end
65
+
66
+ def self.logger
67
+ @logger
68
+ end
69
+ end
70
+ end
71
+ Dir.chdir(File.expand_path('..', File.dirname(__FILE__))) do
72
+ Dir['rb1drv-tools/command/*.rb'].each{ |file| require file }
73
+ end
@@ -0,0 +1,15 @@
1
+ module Rb1drvTools
2
+ module Command
3
+ def self.cmd_cd(args)
4
+ Profile.profile
5
+ dir = args.first
6
+ dir_obj = get_obj(dir)
7
+ if dir_obj.is_a? OneDriveDir
8
+ CLI.cwd = dir_obj
9
+ else
10
+ dir = File.join(CLI.cwd.absolute_path, dir)
11
+ puts "cd: cannot access '#{dir}': No such file or directory"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module Rb1drvTools
2
+ module Command
3
+ def self.get_obj(target)
4
+ if target == '.'
5
+ CLI.cwd
6
+ elsif target == '/'
7
+ CLI.od.root
8
+ elsif target[0] == '/'
9
+ target = File.expand_path('/./' + target)
10
+ CLI.root.get(target)
11
+ else
12
+ target = File.expand_path('/./' + target)
13
+ CLI.cwd.get(target)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,72 @@
1
+ module Rb1drvTools
2
+ module Command
3
+ def self.cmd_help(args)
4
+ cmd_version(args)
5
+ me = File.basename($0, File.extname($0))
6
+ puts <<~EOF
7
+ Usage:
8
+ #{me} [:<profile>] <Command> [-,- <Command>]...
9
+
10
+ Command:
11
+ help Display this help
12
+
13
+ profile new Create a new profile to access your files
14
+ profile ls List profiles
15
+ profile default Set chosen profile as default
16
+ profile del Delete profile to revoke access
17
+
18
+ ls [-ustrl] [<target>] List information about files
19
+ ll [-ustrl] [<target>] Long listing format of ls
20
+ -u Do not sort by name
21
+ -s Sort by size, smallest first
22
+ -t Sort by modified time, oldest first
23
+ -r Reverse order while sorting
24
+ -l Use a long listing format
25
+ directory List contents of this directory
26
+ file List information of this file
27
+
28
+ cd <directory> Change current directory, only effective in single execution
29
+
30
+ mkdir <directory> Create the directory recursively
31
+
32
+ upload [-fs] <files> [@target] Upload files into directory recursively, skipping existing files
33
+ download [-f] <r-files> [@target] Download files into directory recursively, skipping existing files
34
+ -f Overwrite existing files regardless
35
+ -s Overwrite existing files with different size or older date
36
+ @directory/ Upload or download into directory as children, if:
37
+ - target directory exists
38
+ - target ends with a slash
39
+ - multiple source files are given
40
+ - wildcard matching multiple source files
41
+ @file Upload or download as a single file, if:
42
+ - target file exists
43
+ - target does not end with a slash, and only one source file is given
44
+ files Local source files to upload, wildcard accepted in Ruby glob syntax
45
+ r-files Remote source files to download, wildcard accepted with limitations:
46
+ - no ** matching
47
+ - can only match names under current directory
48
+
49
+ info Show information about this drive
50
+
51
+ Examples:
52
+ #{me} profile new student_account
53
+ #{me} profile new personal
54
+ #{me} :personal profile default -,- profile ls
55
+ #{me} :student_account cd class101/slides -,- download slides-2\\*.pdf @slides/
56
+ #{me} upload slides -,- ls -l slides -,- info
57
+
58
+ EOF
59
+ end
60
+
61
+ def self.cmd_version(args)
62
+ puts <<~EOF
63
+ Ruby-OneDrive-Tools #{Rb1drvTools::VERSION}, SDK #{Rb1drv::VERSION}
64
+ Copyright (c) 2018 Xinyue Lu, The MIT License.
65
+
66
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
67
+ You may not hold the author liable. Check LICENSE.txt for Full Text.
68
+
69
+ EOF
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,24 @@
1
+ module Rb1drvTools
2
+ module Command
3
+ def self.cmd_info(args)
4
+ Profile.profile
5
+ format = '%10s: %s'
6
+ CLI.od.request('drives').dig('value').each do |drive|
7
+ {
8
+ 'ID' => drive.dig('id'),
9
+ 'Site' => drive.dig('webUrl'),
10
+ 'Type' => drive.dig('driveType'),
11
+ 'Owner' => '%s <%s>' % [drive.dig('owner', 'user', 'displayName'), drive.dig('owner', 'user', 'email')],
12
+ 'Size' => Utils.humanize_size(drive.dig('quota', 'total')),
13
+ 'Used' => Utils.humanize_size(drive.dig('quota', 'used')),
14
+ 'Deleted' => Utils.humanize_size(drive.dig('quota', 'deleted')),
15
+ 'Free' => Utils.humanize_size(drive.dig('quota', 'remaining'))
16
+ }.each do |row|
17
+ puts format % row
18
+ end
19
+ puts
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,47 @@
1
+ module Rb1drvTools
2
+ module Command
3
+ def self.cmd_ll(args)
4
+ args.unshift('-l')
5
+ cmd_ls(args)
6
+ end
7
+ def self.cmd_ls(args)
8
+ Profile.profile
9
+ column = :name
10
+ order = :asc
11
+ long = false
12
+ dirs = []
13
+ args.each do |arg|
14
+ next dirs << arg if arg[0] != '-'
15
+ arg[1..-1].each_char do |flag|
16
+ case flag
17
+ when 'l'
18
+ long = true
19
+ when 'u'
20
+ column = nil
21
+ when 's'
22
+ column = :size
23
+ when 't'
24
+ column = :mtime
25
+ when 'r'
26
+ order = :desc
27
+ else
28
+ puts "Warning: unknown flag '#{flag}'."
29
+ end
30
+ end
31
+ end
32
+ dirs << '.' if dirs.empty?
33
+ dirs.each do |dir|
34
+ dir_obj = get_obj(dir)
35
+ if dir_obj.is_a? OneDrive404
36
+ dir = File.join(CLI.cwd.absolute_path, dir)
37
+ puts "ls: cannot access '#{dir}': No such file or directory"
38
+ elsif dir_obj.file?
39
+ puts Utils.ls([dir_obj], column, order, long)
40
+ else
41
+ puts Utils.ls(dir_obj.children, column, order, long)
42
+ puts "#{dir_obj.child_count} items"
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,63 @@
1
+ require 'securerandom'
2
+ module Rb1drvTools
3
+ module Command
4
+ def self.cmd_profile(args)
5
+ request = args.shift
6
+ case request
7
+ when nil, 'ls'
8
+ cmd_profile_ls(args)
9
+ when 'new'
10
+ cmd_profile_new(args)
11
+ when 'default'
12
+ cmd_profile_default(args)
13
+ when 'del', 'delete', 'rm'
14
+ cmd_profile_del(args)
15
+ else
16
+ puts "Unknown request #{request}"
17
+ end
18
+ end
19
+
20
+ def self.cmd_profile_ls(args)
21
+ Profile.all.map(&:name).each do |p|
22
+ puts "Profile: #{p}"
23
+ end
24
+ puts "Default: #{Profile.default_profile_index || 'none'}"
25
+ end
26
+
27
+ def self.cmd_profile_new(args)
28
+ name = args.first || SecureRandom.hex(4)
29
+ print <<~EOF.chomp
30
+ Creating profile #{name}.
31
+
32
+ To create a new OneDrive profile, open the following link in your browser, sign in with your account, and approve our access to your files.
33
+
34
+ #{CLI.od.auth_url}
35
+
36
+ Paste your authorization code here:
37
+ EOF
38
+ auth_code = ''
39
+ loop do
40
+ auth_code = STDIN.gets.strip
41
+ break unless auth_code.empty?
42
+ end
43
+ access_token = CLI.od.auth_access(auth_code)
44
+ p = Profile.new
45
+ p.name = name
46
+ p.update_token(access_token)
47
+ end
48
+
49
+ def self.cmd_profile_del(args)
50
+ name = Profile.profile.name
51
+ path = Profile.profile.file
52
+ prompt = TTY::Prompt.new
53
+ puts "You asked to delete your local profile #{name}."
54
+ puts "Doing so will revoke our access to your files."
55
+ puts "You can regain access by `profile add` later."
56
+ File.unlink(path) if prompt.yes?("Proceed to delete?", convert: :bool, default: false)
57
+ end
58
+
59
+ def self.cmd_profile_default(args)
60
+ Profile.default_profile_index = Profile.profile_index
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,138 @@
1
+ module Rb1drvTools
2
+ module Command
3
+ def self.cmd_upload(args)
4
+ Profile.profile
5
+ return if args.empty?
6
+ file_mode = true
7
+ overwrite = false
8
+ overwrite_smarter = false
9
+
10
+ items = []
11
+ args.each do |arg|
12
+ next items << arg if arg[0] != '-'
13
+ arg[1..-1].each_char do |flag|
14
+ case flag
15
+ when 's'
16
+ overwrite_smarter = true
17
+ when 'f'
18
+ overwrite = true
19
+ else
20
+ puts "Warning: unknown flag '#{flag}'."
21
+ end
22
+ end
23
+ end
24
+
25
+ if overwrite && overwrite_smarter
26
+ puts "Error: -s and -f are mutually exclusive, make your decision first."
27
+ return
28
+ end
29
+
30
+ target = '.'
31
+ target = items.pop[1..-1] if items.last[0] == '@'
32
+ target_obj = get_obj(target)
33
+ return if items.empty?
34
+
35
+ # p items
36
+ # p target_obj
37
+
38
+ # Directory mode if:
39
+ # target directory exists
40
+ file_mode = false if target_obj.dir?
41
+ # target ends with a slash
42
+ file_mode = false if target.end_with?('/')
43
+ # multiple source files are given
44
+ file_mode = false if items.size > 1
45
+ file_mode = false if File.directory?(items.first)
46
+ # wildcard matching files on server
47
+ file_mode = false if Dir[items.first].size > 1
48
+
49
+ overwrite_policy = if overwrite
50
+ :overwrite
51
+ elsif overwrite_smarter
52
+ :overwrite_smarter
53
+ else
54
+ :skip
55
+ end
56
+
57
+ if file_mode
58
+ target_dir = get_obj(File.dirname(target))
59
+ CLI.cwd.mkdir(File.dirname(target))
60
+ target_name = File.basename(target)
61
+ upload(items.first, target_dir, File.basename(target), overwrite_policy: overwrite_policy)
62
+ else
63
+ items.each do |item|
64
+ unless target_obj.dir?
65
+ base = if target[0] == '/'
66
+ CLI.root
67
+ else
68
+ CLI.cwd
69
+ end
70
+ target = File.expand_path('/./' + target)
71
+ target_obj = base.mkdir(target)
72
+ end
73
+ Dir[item].each do |match|
74
+ if File.directory?(match)
75
+ traverse_dir(match, target_obj.mkdir(match))
76
+ else
77
+ upload(match, target_obj, File.basename(match), overwrite_policy: overwrite_policy)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ def self.traverse_dir(source_directory, target_directory)
85
+ Dir.children(source_directory).sort.each do |child|
86
+ new_path = File.join(source_directory, child)
87
+ if File.directory?(child)
88
+ new_dir = target_directory.get_child(child)
89
+ new_dir = target_directory.mkdir(child) unless new_dir.dir?
90
+ traverse_dir(new_path, new_dir)
91
+ else
92
+ upload(new_path, target_directory, child)
93
+ end
94
+ end
95
+ end
96
+
97
+ def self.upload(source_file, target_directory, target_name, overwrite_policy: :skip)
98
+ return if source_file.include?('.1drv_upload')
99
+ printf "%s => %s :: %s\n", source_file, target_directory.absolute_path, target_name
100
+ target_obj = target_directory.get_child(target_name)
101
+ return puts 'Target is a directory, skipped' if target_obj.dir?
102
+ if overwrite_policy != :overwrite && target_obj.file?
103
+ return puts 'Skipped' if overwrite_policy == :skip
104
+ return puts 'Remote file is up to date, skipped' if target_obj.mtime >= File.mtime(source_file) - 2
105
+ end
106
+ screen_width = TTY::Screen.width
107
+ if STDOUT.tty? && screen_width >= 50
108
+ multibar = TTY::ProgressBar::Multi.new
109
+ bar = multibar.register("%s :current_byte / :total_byte :byte_rate/s [:bar] :eta :percent" % source_file[0..29], total: File.size(source_file), frequency: 2, head: '>')
110
+ bar.start
111
+ end
112
+ subbar = nil
113
+ # trap(:WINCH) { bar.resize if bar }
114
+
115
+ target_directory.upload(source_file, target_name: target_name, overwrite: true) do |ev, st|
116
+ case ev
117
+ when :new_segment
118
+ subbar = multibar.register("%4d-%-4d :current_byte / :total_byte [:bar]" % [st[:from] / 1048576, st[:to] / 1048576], total: st[:to] - st[:from] + 1, frequency: 2, head: '>')
119
+ when :finish_segment
120
+ subbar.finish
121
+ multibar.instance_variable_get('@bars').delete_at(1)
122
+ multibar.instance_variable_set('@rows', multibar.rows - 1)
123
+ print TTY::Cursor.up(1)
124
+ print TTY::Cursor.clear_line_after
125
+ when :progress
126
+ bar.current = st[:from] + st[:progress]
127
+ subbar.current = st[:progress]
128
+ when :retry
129
+ bar.current = st[:from]
130
+ subbar.reset
131
+ end
132
+ end
133
+
134
+ bar.finish
135
+ end
136
+ singleton_class.send(:alias_method, :cmd_up, :cmd_upload)
137
+ end
138
+ end
@@ -0,0 +1,82 @@
1
+ module Rb1drvTools
2
+ class Profile
3
+ attr_accessor *%w(name token created_at updated_at file)
4
+ def initialize(file=nil)
5
+ @file = file
6
+ if file && File.exist?(file)
7
+ hash_data = JSON.parse(File.read(file))
8
+ %w(name token created_at updated_at).each do |key|
9
+ instance_variable_set("@#{key}", hash_data[key])
10
+ end
11
+ end
12
+ end
13
+
14
+ def update_token(access_token)
15
+ @created_at ||= Time.now.to_i
16
+ @updated_at = Time.now.to_i
17
+ @token = access_token.to_hash
18
+ save
19
+ end
20
+
21
+ def save
22
+ @file ||= File.join(self.class.config_home, "profile-#{@name}.json")
23
+ File.write @file, JSON.pretty_generate(
24
+ name: @name,
25
+ token: @token,
26
+ created_at: @created_at,
27
+ updated_at: @updated_at
28
+ )
29
+ end
30
+
31
+ def self.all
32
+ @all ||= Dir.glob(File.join(config_home, "profile-*.json")).map do |file|
33
+ Profile.new(file)
34
+ end
35
+ end
36
+
37
+ def self.config_home
38
+ home = File.join(Dir.home, '.rb1drv')
39
+ ensure
40
+ FileUtils.mkdir(home) unless File.exist?(home)
41
+ end
42
+
43
+ def self.default_profile_file
44
+ File.join(config_home, 'default-profile')
45
+ end
46
+
47
+ def self.default_profile_index
48
+ @default_profile_index ||=
49
+ if File.exist?(default_profile_file)
50
+ File.read(default_profile_file).strip
51
+ else
52
+ nil
53
+ end
54
+ end
55
+
56
+ def self.default_profile_index=value
57
+ return if value.empty?
58
+ @default_profile_index = value
59
+ File.write(default_profile_file, value)
60
+ end
61
+
62
+ def self.profile_index
63
+ @profile_index
64
+ end
65
+ def self.profile_index=(name)
66
+ return unless name
67
+ @profile_index = name
68
+ @profile = all.select{ |p| p.name == name }.first
69
+ token = @profile.token
70
+ new_token = CLI.od.auth_load(token)
71
+ @profile.update_token(new_token) if new_token.token != token
72
+ end
73
+
74
+ def self.profile
75
+ raise 'No profile available' if all.empty?
76
+ self.profile_index ||= all.first.name if all.size == 1
77
+ self.profile_index ||= default_profile_index
78
+ raise 'Invalid profile' unless @profile
79
+ @profile
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,64 @@
1
+ module Rb1drvTools
2
+ module Utils
3
+ module_function
4
+ def sort_files(items, column, order)
5
+ if column
6
+ items = items.sort_by(&column)
7
+ items = items.reverse if order == :desc
8
+ end
9
+ items
10
+ end
11
+ def ls(items, column = :name, order = :asc, long = false, width=0)
12
+ return ll(items, column, order) if long
13
+ items = sort_files(items, column, order).map(&:name)
14
+ if width > 0
15
+ ls_format(items, width)
16
+ else
17
+ ls_simple(items)
18
+ end
19
+ end
20
+
21
+ def ls_simple(items)
22
+ items.join($/)
23
+ end
24
+
25
+ def ls_format(items, width)
26
+ buffer = []
27
+ lens = items.map(&:size)
28
+ row_length = []
29
+ rows = 1.upto(items.size) do |rows|
30
+ row_length = lens.each_slice(rows).map{ |col| col.max + 2 }
31
+ usage = row_length.sum
32
+ break rows if usage < width
33
+ end
34
+ items.each_slice(rows).reduce(&:zip).map(&:flatten).each do |row|
35
+ row.each_with_index do |item, idx|
36
+ buffer << item.ljust(row_length[idx]) if item
37
+ end
38
+ buffer << $/
39
+ end
40
+ buffer.join
41
+ end
42
+
43
+ def ll(items, column = :name, order = :asc)
44
+ items = sort_files(items, column, order)
45
+ items.map do |item|
46
+ if item.dir?
47
+ sprintf("d %-4d %-20s %6s %s %s/", item.child_count, item.muser, humanize_size(item.size), item.mtime.localtime.strftime('%Y-%m-%d %H:%M:%S'), item.name)
48
+ else
49
+ sprintf("f %-4d %-20s %6s %s %s", 0, item.muser, humanize_size(item.size), item.mtime.localtime.strftime('%Y-%m-%d %H:%M:%S'), item.name)
50
+ end
51
+ end.join($/)
52
+ end
53
+
54
+ def humanize_size(size)
55
+ units = ['', 'K', 'M', 'G']
56
+ unit_idx = 0
57
+ while size > 8192 && unit_idx < units.size - 1 do
58
+ size /= 1024
59
+ unit_idx += 1
60
+ end
61
+ "#{size}#{units[unit_idx]}"
62
+ end
63
+ end
64
+ end
@@ -1,3 +1,3 @@
1
1
  module Rb1drvTools
2
- VERSION = "0.0.0placeholder"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Xinyue Lu"]
10
10
  spec.email = ["i@7086.in"]
11
11
 
12
- spec.summary = "Ruby OneDrive CLI"
12
+ spec.summary = "Ruby OneDrive Library Tools"
13
13
  spec.homepage = "https://github.com/msg7086/rb1drv-tools"
14
14
  spec.license = "MIT"
15
15
 
@@ -19,8 +19,12 @@ Gem::Specification.new do |spec|
19
19
  spec.bindir = "exe"
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
+ spec.required_ruby_version = '>= 2.5'
22
23
 
23
24
  spec.add_dependency "rb1drv", "~> 0.1"
25
+ spec.add_dependency "tty-progressbar", "~> 0"
26
+ spec.add_dependency "tty-prompt", "~> 0"
27
+ spec.add_dependency "tty-screen", "~> 0"
24
28
  spec.add_development_dependency "bundler", "~> 1.16"
25
29
  spec.add_development_dependency "rake", "~> 10.0"
26
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rb1drv-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0placeholder
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xinyue Lu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-17 00:00:00.000000000 Z
11
+ date: 2018-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rb1drv
@@ -24,6 +24,48 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: tty-progressbar
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: tty-prompt
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: tty-screen
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: bundler
29
71
  requirement: !ruby/object:Gem::Requirement
@@ -55,12 +97,31 @@ dependencies:
55
97
  description:
56
98
  email:
57
99
  - i@7086.in
58
- executables: []
100
+ executables:
101
+ - 1d
59
102
  extensions: []
60
103
  extra_rdoc_files: []
61
104
  files:
105
+ - ".gitignore"
106
+ - ".travis.yml"
107
+ - Gemfile
108
+ - Gemfile.lock
62
109
  - LICENSE.txt
63
110
  - README.md
111
+ - bin/console
112
+ - bin/setup
113
+ - exe/1d
114
+ - lib/rb1drv-tools.rb
115
+ - lib/rb1drv-tools/cli.rb
116
+ - lib/rb1drv-tools/command/cd.rb
117
+ - lib/rb1drv-tools/command/common.rb
118
+ - lib/rb1drv-tools/command/help.rb
119
+ - lib/rb1drv-tools/command/info.rb
120
+ - lib/rb1drv-tools/command/ls.rb
121
+ - lib/rb1drv-tools/command/profile.rb
122
+ - lib/rb1drv-tools/command/upload.rb
123
+ - lib/rb1drv-tools/profile.rb
124
+ - lib/rb1drv-tools/utils.rb
64
125
  - lib/rb1drv-tools/version.rb
65
126
  - rb1drv-tools.gemspec
66
127
  homepage: https://github.com/msg7086/rb1drv-tools
@@ -75,16 +136,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
75
136
  requirements:
76
137
  - - ">="
77
138
  - !ruby/object:Gem::Version
78
- version: '0'
139
+ version: '2.5'
79
140
  required_rubygems_version: !ruby/object:Gem::Requirement
80
141
  requirements:
81
- - - ">"
142
+ - - ">="
82
143
  - !ruby/object:Gem::Version
83
- version: 1.3.1
144
+ version: '0'
84
145
  requirements: []
85
146
  rubyforge_project:
86
147
  rubygems_version: 2.7.6
87
148
  signing_key:
88
149
  specification_version: 4
89
- summary: Ruby OneDrive CLI
150
+ summary: Ruby OneDrive Library Tools
90
151
  test_files: []