rb1drv-tools 0.0.0placeholder → 0.1.0

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
  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: []