gdrive-cli 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3b610f46c0797a2e97953ff318408e96203192319e9ac0993a8b74bb1b46b0d1
4
+ data.tar.gz: 6ddf89868fc9c6b742111b43bbaa64da68cc17bc0dacd2b8259ef0c69b559467
5
+ SHA512:
6
+ metadata.gz: 1aec88e81e6feba4c09e73d03c449f38c628aa4d605f9e8885f78431cfa971fe0d0c9badef2c294a2f7a1679a490443eefdd0bca11ef6322add036dcb1917f6b
7
+ data.tar.gz: e81da2d9c099714b8ca2ea8545eff776900fd1d5160eba7a1ff559d043ece522dc7ed4cffc6736202472c214c3a585ed5037ad7ddf4c67173983dc05cbd67920
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'google_drive'
data/Gemfile.lock ADDED
@@ -0,0 +1,63 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ addressable (2.7.0)
5
+ public_suffix (>= 2.0.2, < 5.0)
6
+ declarative (0.0.20)
7
+ declarative-option (0.1.0)
8
+ faraday (1.1.0)
9
+ multipart-post (>= 1.2, < 3)
10
+ ruby2_keywords
11
+ google-api-client (0.50.0)
12
+ addressable (~> 2.5, >= 2.5.1)
13
+ googleauth (~> 0.9)
14
+ httpclient (>= 2.8.1, < 3.0)
15
+ mini_mime (~> 1.0)
16
+ representable (~> 3.0)
17
+ retriable (>= 2.0, < 4.0)
18
+ rexml
19
+ signet (~> 0.12)
20
+ google_drive (3.0.5)
21
+ google-api-client (>= 0.11.0, < 1.0.0)
22
+ googleauth (>= 0.5.0, < 1.0.0)
23
+ nokogiri (>= 1.5.3, < 2.0.0)
24
+ googleauth (0.14.0)
25
+ faraday (>= 0.17.3, < 2.0)
26
+ jwt (>= 1.4, < 3.0)
27
+ memoist (~> 0.16)
28
+ multi_json (~> 1.11)
29
+ os (>= 0.9, < 2.0)
30
+ signet (~> 0.14)
31
+ httpclient (2.8.3)
32
+ jwt (2.2.2)
33
+ memoist (0.16.2)
34
+ mini_mime (1.0.2)
35
+ mini_portile2 (2.4.0)
36
+ multi_json (1.15.0)
37
+ multipart-post (2.1.1)
38
+ nokogiri (1.10.10)
39
+ mini_portile2 (~> 2.4.0)
40
+ os (1.1.1)
41
+ public_suffix (4.0.6)
42
+ representable (3.0.4)
43
+ declarative (< 0.1.0)
44
+ declarative-option (< 0.2.0)
45
+ uber (< 0.2.0)
46
+ retriable (3.1.2)
47
+ rexml (3.2.4)
48
+ ruby2_keywords (0.0.2)
49
+ signet (0.14.0)
50
+ addressable (~> 2.3)
51
+ faraday (>= 0.17.3, < 2.0)
52
+ jwt (>= 1.5, < 3.0)
53
+ multi_json (~> 1.10)
54
+ uber (0.1.0)
55
+
56
+ PLATFORMS
57
+ ruby
58
+
59
+ DEPENDENCIES
60
+ google_drive
61
+
62
+ BUNDLED WITH
63
+ 2.1.4
data/README.md ADDED
File without changes
data/bin/gdrive ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pry'
4
+ require 'json'
5
+ begin
6
+ require_relative '../lib/gdrive-lib'
7
+ rescue LoadError
8
+ abort "You need to install the google_drive gem first."
9
+ end
10
+
11
+ CREDENTIALS_FILE_PATH = File.expand_path('~/.gdrive.json')
12
+ CLI.ensure_credentials_file(CREDENTIALS_FILE_PATH)
13
+
14
+ cli = CLI.build(CREDENTIALS_FILE_PATH)
15
+
16
+ case ARGV.shift
17
+ when 'list', 'ls' then cli.command_list(ARGV.first)
18
+ when 'find' then cli.command_find(ARGV.first)
19
+ when 'search' then cli.command_search(ARGV.first)
20
+ when 'cat' then cli.command_cat(ARGV.first)
21
+ when 'download' then cli.command_download(*ARGV[0..2])
22
+ when 'upload' then cli.command_upload(*ARGV)
23
+ when 'mkdir' then cli.command_mkdir(ARGV.first)
24
+ when 'remove', 'rm' then cli.command_remove(ARGV.first)
25
+ else
26
+ puts eval("\"#{DATA.read}\"")
27
+ end
28
+
29
+ __END__
30
+ #{`tput setaf 9`}Usage:#{`tput sgr0`}
31
+
32
+ #{`tput setaf 10`}#{File.basename($0)} ls [path]#{`tput sgr0`} List given path. If no path is given, root is assummed.
33
+ #{`tput setaf 10`}#{File.basename($0)} find [path]#{`tput sgr0`} List given path recursively. If no path is given, root is assummed.
34
+ #{`tput setaf 10`}#{File.basename($0)} search [title]#{`tput sgr0`} Look for file title.
35
+
36
+ #{`tput setaf 11`}#{File.basename($0)} mkdir [path]#{`tput sgr0`} Create a directory.
37
+ #{`tput setaf 11`}#{File.basename($0)} download [path]#{`tput sgr0`} Download a file.
38
+ #{`tput setaf 11`}#{File.basename($0)} upload [local paths] [remote path]#{`tput sgr0`} Upload file(s) into a remote path. Remote path doesn't have to exist yet, but its dirname has to exist.
39
+ #{`tput setaf 11`}#{File.basename($0)} cat [path]#{`tput sgr0`} Print out remote file.
40
+
41
+ #{`tput setaf 9`}#{File.basename($0)} remove [remote path]#{`tput sgr0`} Delete remote file.
@@ -0,0 +1,12 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = 'gdrive-cli'
3
+ spec.version = '0.0.2'
4
+ spec.license = 'MIT' # Just so gem build would shut up. Use it however you like.
5
+
6
+ spec.summary = "Manage your Google Drive from command line"
7
+ spec.author = "Jakub Šťastný"
8
+ spec.homepage = 'https://github.com/jakub-stastny/gdrive-cli'
9
+
10
+ spec.files = Dir["{lib,spec}/**/*.rb"] + Dir["bin/*"] + ['Gemfile', 'Gemfile.lock', 'README.md', 'gdrive-cli.gemspec']
11
+ spec.executables << 'gdrive'
12
+ end
data/lib/gdrive-lib.rb ADDED
@@ -0,0 +1,186 @@
1
+ require 'google_drive'
2
+
3
+ # TODO: double upload shouldn't be possible (same file name), but is is now.
4
+ class CLI
5
+ class InvalidPathError < StandardError
6
+ end
7
+
8
+ class ErrorNotDirectory < StandardError
9
+ attr_reader :file
10
+ def initialize(file)
11
+ @file = file
12
+ end
13
+ end
14
+
15
+ # This has to be a file, so it can be updated with scope and refresh token (automatically).
16
+ def self.ensure_credentials_file(credentials_file_path)
17
+ unless File.file?(credentials_file_path)
18
+ id = ENV.fetch('GDRIVE_CLIENT_ID')
19
+ secret = ENV.fetch('GDRIVE_CLIENT_SECRET')
20
+
21
+ File.open(credentials_file_path, 'w') do |file|
22
+ file.puts({client_id: id, client_secret: secret}.to_json)
23
+ end
24
+ end
25
+ end
26
+
27
+ # Creates a session. This will prompt the credential via command line for the
28
+ # first time and save it to config.json file for later usages.
29
+ # See this document to learn how to create config.json:
30
+ # https://github.com/gimite/google-drive-ruby/blob/master/doc/authorization.md
31
+ def self.build(credentials_file_path)
32
+ self.new(GoogleDrive::Session.from_config(credentials_file_path))
33
+ end
34
+
35
+ def initialize(session)
36
+ @session = session
37
+ end
38
+
39
+ def command_list(destination)
40
+ collection = self.get_collection(destination)
41
+ collection.files.uniq(&:title).sort_by(&:title).each do |file|
42
+ puts file.is_a?(GoogleDrive::Collection) ? "#{`tput setaf 4`}#{file.title}#{`tput sgr0`}" : file.title
43
+ end
44
+ rescue ErrorNotDirectory => error # If given path points to a file, show more details.
45
+ p error.file
46
+ rescue Interrupt
47
+ puts
48
+ end
49
+
50
+ def command_find(destination)
51
+ self.find(self.get_collection(destination))
52
+ rescue ErrorNotDirectory => error # If given path points to a file, show more details.
53
+ p error.file
54
+ rescue Interrupt
55
+ puts
56
+ end
57
+
58
+ # FIXME: Doesn't work.
59
+ def command_search(title)
60
+ drive_service = @session.instance_variable_get(:@fetcher).drive
61
+ query = "title contains '#{ARGV.first}'"
62
+ puts "Query: #{query}"
63
+ files = drive_service.list_files(q: query)
64
+ files.items.each do |file|
65
+ puts file.title
66
+ end
67
+ rescue Interrupt
68
+ puts
69
+ end
70
+
71
+ def command_cat(remote_path)
72
+ remote_path, local_path = ARGV
73
+ local_path ||= File.basename(remote_path)
74
+ file = self.find_file(remote_path)
75
+ file || abort("File #{remote_path} not found")
76
+ if file.is_a?(GoogleDrive::Collection)
77
+ abort "File #{remote_path} is a directory"
78
+ else
79
+ puts file.download_to_string
80
+ end
81
+ rescue Interrupt
82
+ puts
83
+ end
84
+
85
+ def command_download(remote_path, local_path = File.basename(remote_path))
86
+ puts "~ Downloading '#{remote_path}' to #{local_path}"
87
+ download(remote_path, local_path)
88
+ rescue Interrupt
89
+ puts
90
+ end
91
+
92
+ # Upload to WIP:
93
+ # upload song.mp3 song2.mp3
94
+ # upload song.mp3 song2.mp3 -- songs
95
+ def command_upload(*args)
96
+ if separator_index = args.index('--')
97
+ local_paths = args[0..(separator_index - 1)]
98
+ remote_paths = args[(separator_index + 1)..-1]
99
+ if remote_path.length != 1
100
+ abort "x"
101
+ end
102
+ remote_path = remote_paths.first
103
+ else
104
+ local_paths = args
105
+ remote_path = local_paths.length == 1 ? local_paths.first : 'WIP'
106
+ end
107
+ require 'pry'; binding.pry ###
108
+ local_path, remote_path = "/#{File.basename(local_path)}"
109
+ # If path is given as relative, File.dirname(remote_path) returns '.' and
110
+ # self.find_file returns nil.
111
+ remote_path = "/#{remote_path}" unless remote_path.start_with?('/')
112
+
113
+ puts "~ Uploading '#{local_path}' to #{remote_path}"
114
+ file = @session.upload_from_file(local_path, File.basename(remote_path), convert: false)
115
+
116
+ # File is always uploaded to the root_collection by default.
117
+ # https://github.com/gimite/google-drive-ruby/issues/260
118
+ unless self.find_file(File.dirname(remote_path)) == @session.root_collection
119
+ require 'pry'; binding.pry ###
120
+ self.find_file(File.dirname(remote_path)).add(file)
121
+ @session.root_collection.remove(file)
122
+ end
123
+ rescue Interrupt
124
+ puts
125
+ end
126
+
127
+ def command_mkdir(remote_path)
128
+ *dirnames, basename = ARGV.first.split('/')
129
+ collection = dirnames.empty? ? @session.root_collection : self.find_file(dirnames.join('/'))
130
+ collection.create_subcollection(ARGV.first.split('/').last)
131
+ rescue Interrupt
132
+ puts
133
+ end
134
+
135
+ def command_remove(remote_path)
136
+ puts "~ Deleting '#{ARGV.first}'"
137
+ file = self.find_file(ARGV.first)
138
+ file.delete(true)
139
+ rescue Interrupt
140
+ puts
141
+ end
142
+
143
+ protected
144
+ def get_collection(destination)
145
+ result = destination.nil? || destination == '/' ? @session.root_collection : self.find_file(destination.sub(/^\//, ''))
146
+ raise InvalidPathError if result.nil?
147
+ raise ErrorNotDirectory.new(result) unless result.respond_to?(:create_subcollection)
148
+ result
149
+ end
150
+
151
+ def find_file(full_path)
152
+ full_path.split('/').reduce(@session.root_collection) do |parent, file_name|
153
+ parent.file_by_title(file_name)
154
+ end
155
+ end
156
+
157
+ def download(remote_path, local_path)
158
+ file = self.find_file(remote_path)
159
+ file || abort("File #{remote_path} not found")
160
+ if file.is_a?(GoogleDrive::Collection)
161
+ Dir.mkdir(local_path)
162
+ Dir.chdir(local_path) do
163
+ file.files.each do |file|
164
+ download(file)
165
+ end
166
+ end
167
+ else
168
+ file.download_to_file(local_path)
169
+ end
170
+ rescue NotImplementedError
171
+ # This will want the format to be specified most likely.
172
+ #
173
+ # file.export_as_file(local_path)
174
+ binding.pry
175
+ end
176
+
177
+ def find(collection, dirname = nil)
178
+ collection.files.uniq(&:title).sort_by(&:title).each do |file|
179
+ if file.is_a?(GoogleDrive::Collection)
180
+ self.find(file, [dirname, file.title].compact.join('/'))
181
+ else
182
+ puts [dirname, file.title].compact.join('/')
183
+ end
184
+ end
185
+ end
186
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gdrive-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Jakub Šťastný
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-12-03 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ executables:
16
+ - gdrive
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - Gemfile
21
+ - Gemfile.lock
22
+ - README.md
23
+ - bin/gdrive
24
+ - gdrive-cli.gemspec
25
+ - lib/gdrive-lib.rb
26
+ homepage: https://github.com/jakub-stastny/gdrive-cli
27
+ licenses:
28
+ - MIT
29
+ metadata: {}
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubygems_version: 3.1.2
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: Manage your Google Drive from command line
49
+ test_files: []