gdsh 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rspec +1 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +1 -0
- data/bin/gdsh +10 -0
- data/document.txt +2 -0
- data/gdsh.gemspec +28 -0
- data/lib/gdsh.rb +61 -0
- data/lib/gdsh/clear.rb +20 -0
- data/lib/gdsh/command_factory.rb +32 -0
- data/lib/gdsh/command_mixin.rb +46 -0
- data/lib/gdsh/commands.rb +53 -0
- data/lib/gdsh/drive.rb +113 -0
- data/lib/gdsh/error.rb +7 -0
- data/lib/gdsh/get_file.rb +65 -0
- data/lib/gdsh/help.rb +20 -0
- data/lib/gdsh/list_files.rb +78 -0
- data/lib/gdsh/mime.rb +52 -0
- data/lib/gdsh/query_revision.rb +106 -0
- data/lib/gdsh/quit.rb +23 -0
- data/lib/gdsh/remove.rb +34 -0
- data/lib/gdsh/revision_diff.rb +87 -0
- data/lib/gdsh/share.rb +65 -0
- data/lib/gdsh/share_read_only.rb +18 -0
- data/lib/gdsh/share_read_write.rb +18 -0
- data/lib/gdsh/unrecognized.rb +12 -0
- data/lib/gdsh/upload_template.rb +52 -0
- data/lib/gdsh/version.rb +6 -0
- data/spec/commands_spec.rb +41 -0
- metadata +175 -0
data/lib/gdsh/error.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require_relative 'commands'
|
2
|
+
require_relative 'query_revision'
|
3
|
+
|
4
|
+
module Commands
|
5
|
+
##
|
6
|
+
# Downloads Files/Revisions
|
7
|
+
#
|
8
|
+
class GetFile < QueryRevision
|
9
|
+
def self.command_name
|
10
|
+
'get_txt'
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.parameters
|
14
|
+
'(<file_id>[,<revision_number>])'
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.function
|
18
|
+
'Downloads a specific revision of a file if <revision_number> is ' \
|
19
|
+
'specified; downloads all revisions otherwise.'
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(client, params)
|
23
|
+
super(client, params)
|
24
|
+
@revision = (params.length == 3) ? params[2] : nil
|
25
|
+
@file_id = @params[1]
|
26
|
+
end
|
27
|
+
|
28
|
+
def puts_downloading_banner(url)
|
29
|
+
puts 'Downloading '.colorize(:cyan) + "#{url} ...".colorize(:light_yellow)
|
30
|
+
end
|
31
|
+
|
32
|
+
def download(url)
|
33
|
+
return unless @client
|
34
|
+
|
35
|
+
puts_downloading_banner(url)
|
36
|
+
result = @client.execute(uri: url)
|
37
|
+
if result.status == 200
|
38
|
+
result.body
|
39
|
+
else
|
40
|
+
puts drive_error_string
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def download_revision_as_txt(rev)
|
45
|
+
download(txt_link(rev))
|
46
|
+
end
|
47
|
+
|
48
|
+
def write_to_file(revision)
|
49
|
+
filename = generate_filename_from_revision(revision)
|
50
|
+
File.write(filename, download_revision_as_txt(revision))
|
51
|
+
end
|
52
|
+
|
53
|
+
def generate_filename_from_revision(revision)
|
54
|
+
@file_id + '_rev_' + revision + '.txt'
|
55
|
+
end
|
56
|
+
|
57
|
+
def execute
|
58
|
+
if @revision.nil?
|
59
|
+
revisions.each { |r| write_to_file(r['id']) }
|
60
|
+
else
|
61
|
+
write_to_file(@revision)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/gdsh/help.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'commands'
|
2
|
+
|
3
|
+
module Commands
|
4
|
+
##
|
5
|
+
# Help command
|
6
|
+
#
|
7
|
+
class Help < Command
|
8
|
+
def self.command_name
|
9
|
+
'help'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.function
|
13
|
+
'Returns this usage information.'
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
Commands.usage
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require_relative 'commands'
|
2
|
+
|
3
|
+
module Commands
|
4
|
+
##
|
5
|
+
# List all files accessible by the application.
|
6
|
+
#
|
7
|
+
class ListFiles < Command
|
8
|
+
def self.command_name
|
9
|
+
'ls'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.function
|
13
|
+
'List files accessible by this application.'
|
14
|
+
end
|
15
|
+
|
16
|
+
def retrieve_file_by_page_token(pagetoken)
|
17
|
+
parameters = pagetoken.to_s.empty? ? {} : { pageToken: pagetoken }
|
18
|
+
drive = @client.discovered_api('drive', 'v2')
|
19
|
+
@client.execute(
|
20
|
+
api_method: drive.files.list,
|
21
|
+
parameters: parameters)
|
22
|
+
end
|
23
|
+
|
24
|
+
def puts_banner
|
25
|
+
puts 'Retrieving list of files accessible...'.colorize(:green)
|
26
|
+
end
|
27
|
+
|
28
|
+
def filelist
|
29
|
+
puts_banner
|
30
|
+
|
31
|
+
result = []
|
32
|
+
page_token = nil
|
33
|
+
|
34
|
+
loop do
|
35
|
+
api_result = retrieve_file_by_page_token(page_token)
|
36
|
+
|
37
|
+
if api_result.status == 200
|
38
|
+
files = api_result.data
|
39
|
+
result.concat(files.items)
|
40
|
+
page_token = files.next_page_token
|
41
|
+
else
|
42
|
+
drive_error_string
|
43
|
+
page_token = nil
|
44
|
+
end
|
45
|
+
|
46
|
+
break if page_token.to_s.empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
result
|
50
|
+
end
|
51
|
+
|
52
|
+
def title_label
|
53
|
+
'Title: '.colorize(:light_magenta)
|
54
|
+
end
|
55
|
+
|
56
|
+
def id_label
|
57
|
+
'id: '.colorize(:light_magenta)
|
58
|
+
end
|
59
|
+
|
60
|
+
def created_at_label
|
61
|
+
'created at: '.colorize(:light_magenta)
|
62
|
+
end
|
63
|
+
|
64
|
+
def puts_file_info(f)
|
65
|
+
puts title_label + "#{f['title']}"
|
66
|
+
puts id_label + "#{f['id']}"
|
67
|
+
puts created_at_label + "#{f['createdDate']}"
|
68
|
+
puts ''
|
69
|
+
end
|
70
|
+
|
71
|
+
def execute
|
72
|
+
filelist.each do |f|
|
73
|
+
next if f['labels']['trashed']
|
74
|
+
puts_file_info(f)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/gdsh/mime.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
##
|
2
|
+
# MIME types supported by Google Drive.
|
3
|
+
#
|
4
|
+
module Mime
|
5
|
+
def html
|
6
|
+
'text/html'
|
7
|
+
end
|
8
|
+
|
9
|
+
def txt
|
10
|
+
'text/plain'
|
11
|
+
end
|
12
|
+
|
13
|
+
def rtf
|
14
|
+
'application/rtf'
|
15
|
+
end
|
16
|
+
|
17
|
+
def odt
|
18
|
+
'application/vnd.oasis.opendocument.text'
|
19
|
+
end
|
20
|
+
|
21
|
+
def pdf
|
22
|
+
'application/pdf'
|
23
|
+
end
|
24
|
+
|
25
|
+
def docx
|
26
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
|
27
|
+
end
|
28
|
+
|
29
|
+
def xlsx
|
30
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
31
|
+
end
|
32
|
+
|
33
|
+
def ods
|
34
|
+
'application/x-vnd.oasis.opendocument.spreadsheet'
|
35
|
+
end
|
36
|
+
|
37
|
+
def jpeg
|
38
|
+
'image/jpeg'
|
39
|
+
end
|
40
|
+
|
41
|
+
def png
|
42
|
+
'image/png'
|
43
|
+
end
|
44
|
+
|
45
|
+
def svg
|
46
|
+
'image/svg+xml'
|
47
|
+
end
|
48
|
+
|
49
|
+
def pptx
|
50
|
+
'application/vnd.openxmlformats-officedocument.presentationml.presentation'
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require_relative 'commands'
|
2
|
+
require_relative 'mime'
|
3
|
+
|
4
|
+
module Commands
|
5
|
+
##
|
6
|
+
# Queries all revisions of a file.
|
7
|
+
#
|
8
|
+
class QueryRevision < Command
|
9
|
+
include Mime
|
10
|
+
|
11
|
+
def self.command_name
|
12
|
+
'query'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.parameters
|
16
|
+
'(<file_id>)'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.function
|
20
|
+
'Queries all revisions of a file.'
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(client, params)
|
24
|
+
super(client, params)
|
25
|
+
@file_id = params[1]
|
26
|
+
end
|
27
|
+
|
28
|
+
def revisions
|
29
|
+
drive = @client.discovered_api('drive', 'v2')
|
30
|
+
api_result = @client.execute(
|
31
|
+
api_method: drive.revisions.list,
|
32
|
+
parameters: { 'fileId' => @file_id })
|
33
|
+
if api_result.status == 200
|
34
|
+
api_result.data.items
|
35
|
+
else
|
36
|
+
puts drive_error_string
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def puts_banner
|
41
|
+
puts 'Revisions'.colorize(:magenta)
|
42
|
+
puts '---------'.colorize(:magenta)
|
43
|
+
end
|
44
|
+
|
45
|
+
def revision_id_label
|
46
|
+
'Revision id: '.colorize(:magenta)
|
47
|
+
end
|
48
|
+
|
49
|
+
def modified_date_label
|
50
|
+
'Modified: '.colorize(:magenta)
|
51
|
+
end
|
52
|
+
|
53
|
+
def modifying_user_label
|
54
|
+
'Modifying User: '.colorize(:magenta)
|
55
|
+
end
|
56
|
+
|
57
|
+
def pdf_link_label
|
58
|
+
'Download pdf: '.colorize(:magenta)
|
59
|
+
end
|
60
|
+
|
61
|
+
def docx_link_label
|
62
|
+
'Download docx: '.colorize(:magenta)
|
63
|
+
end
|
64
|
+
|
65
|
+
def txt_link_label
|
66
|
+
'Download txt: '.colorize(:magenta)
|
67
|
+
end
|
68
|
+
|
69
|
+
def puts_download_links(revision)
|
70
|
+
puts pdf_link_label + "#{revision['exportLinks'][pdf]}"
|
71
|
+
puts docx_link_label + "#{revision['exportLinks'][docx]}"
|
72
|
+
puts txt_link_label + "#{revision['exportLinks'][txt]}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def puts_revision_info(revision)
|
76
|
+
puts revision_id_label + "#{revision['id']}"
|
77
|
+
puts modified_date_label + "#{revision['modifiedDate']}"
|
78
|
+
puts modifying_user_label + "#{revision['lastModifyingUserName']}"
|
79
|
+
puts_download_links
|
80
|
+
puts ''
|
81
|
+
end
|
82
|
+
|
83
|
+
def execute
|
84
|
+
return if revisions.nil?
|
85
|
+
|
86
|
+
puts_banner
|
87
|
+
revisions.each do |r|
|
88
|
+
puts_revision_info(r)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def txt_link(revision)
|
93
|
+
rev = revisions.select { |r| r['id'] == revision }
|
94
|
+
# should only have one element if revision exists
|
95
|
+
rev.first['exportLinks'][txt] unless rev.empty?
|
96
|
+
end
|
97
|
+
|
98
|
+
def modifying_users
|
99
|
+
modifying_hash = {}
|
100
|
+
revisions.each do |r|
|
101
|
+
modifying_hash[r['id']] = r['lastModifyingUserName']
|
102
|
+
end
|
103
|
+
modifying_hash
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/gdsh/quit.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'commands'
|
2
|
+
|
3
|
+
module Commands
|
4
|
+
##
|
5
|
+
# Quit command.
|
6
|
+
#
|
7
|
+
class Quit < Command
|
8
|
+
def self.command_name
|
9
|
+
'quit'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.function
|
13
|
+
'Exit the application.'
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.terminal?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/gdsh/remove.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative 'commands'
|
2
|
+
|
3
|
+
module Commands
|
4
|
+
class Remove < Command
|
5
|
+
def self.command_name
|
6
|
+
'rm'
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.parameters
|
10
|
+
'(<file_id>)'
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.function
|
14
|
+
'Removes the file.'
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(client, params)
|
18
|
+
super(client, params)
|
19
|
+
@file_id = @params[1]
|
20
|
+
end
|
21
|
+
|
22
|
+
def execute
|
23
|
+
drive = @client.discovered_api('drive', 'v2')
|
24
|
+
result = @client.execute(
|
25
|
+
api_method: drive.files.trash,
|
26
|
+
parameters: { fileId: @file_id })
|
27
|
+
if result.status != 200
|
28
|
+
puts drive_error_string
|
29
|
+
else
|
30
|
+
puts 'Deleted.'.colorize(:green)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'differ'
|
2
|
+
|
3
|
+
require_relative 'commands'
|
4
|
+
require_relative 'get_file'
|
5
|
+
|
6
|
+
module Commands
|
7
|
+
##
|
8
|
+
# Summarizes changes between revisions
|
9
|
+
#
|
10
|
+
class RevisionDiff < GetFile
|
11
|
+
def self.command_name
|
12
|
+
'diff'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.parameters
|
16
|
+
'(<file_id>[, <rev_1>, <rev_2>])'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.function
|
20
|
+
'Compares and summarizes the changes between two revisions. If no ' \
|
21
|
+
'revision numbers are provided, a consolidated summary is returned.'
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(client, params)
|
25
|
+
super(client, params)
|
26
|
+
init_revisions
|
27
|
+
end
|
28
|
+
|
29
|
+
def init_revisions
|
30
|
+
@low_rev = (@params.length == 4) ? @params[2] : nil
|
31
|
+
@high_rev = (@params.length == 4) ? @params[3] : nil
|
32
|
+
@all = @low_rev.nil? && @high_rev.nil?
|
33
|
+
return if @all || order_is_correct
|
34
|
+
@low_rev, @high_rev = @high_rev, @low_rev
|
35
|
+
end
|
36
|
+
|
37
|
+
def order_is_correct
|
38
|
+
@high_rev.to_i > @low_rev.to_i
|
39
|
+
end
|
40
|
+
|
41
|
+
def consecutive_revisions
|
42
|
+
return unless @all
|
43
|
+
keys = modifying_users.keys.sort_by { |x| x.to_i }
|
44
|
+
len = keys.length
|
45
|
+
keys.first(len - 1).zip(keys.last(len - 1))
|
46
|
+
end
|
47
|
+
|
48
|
+
def compare_two_revs(low, high)
|
49
|
+
first = download_revision_as_txt(low)
|
50
|
+
second = download_revision_as_txt(high)
|
51
|
+
Differ.diff_by_word(first, second)
|
52
|
+
end
|
53
|
+
|
54
|
+
def print_summary_of_changes(changes)
|
55
|
+
puts "#{changes.change_count} words changed, ".colorize(:green) +
|
56
|
+
"#{changes.insert_count} inserts, ".colorize(:green) +
|
57
|
+
"#{changes.delete_count} deletes.".colorize(:green)
|
58
|
+
end
|
59
|
+
|
60
|
+
def compare_and_print_change_count(low, high)
|
61
|
+
changes = compare_two_revs(low, high)
|
62
|
+
print_summary_of_changes(changes)
|
63
|
+
end
|
64
|
+
|
65
|
+
def puts_diff_note
|
66
|
+
puts "Note: 'ab' -> 'ac' counts as both an insert and".colorize(:green) +
|
67
|
+
' a delete but counts as only one change.'.colorize(:green)
|
68
|
+
end
|
69
|
+
|
70
|
+
def diff_author(pair)
|
71
|
+
"From rev #{pair[0]} to rev #{pair[1]} ".colorize(:green) +
|
72
|
+
"modified by #{modifying_users[pair[0]]}".colorize(:green)
|
73
|
+
end
|
74
|
+
|
75
|
+
def execute
|
76
|
+
puts_diff_note
|
77
|
+
if @all
|
78
|
+
consecutive_revisions.each do |pair|
|
79
|
+
puts diff_author(pair)
|
80
|
+
compare_and_print_change_count(pair[0], pair[1])
|
81
|
+
end
|
82
|
+
else
|
83
|
+
compare_and_print_change_count(@low_rev, @high_rev)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|