drive_v3 0.2.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 +7 -0
- data/.markdownlint.yml +25 -0
- data/.rspec +3 -0
- data/.rubocop.yml +37 -0
- data/.yardopts +6 -0
- data/CHANGELOG.md +24 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.txt +21 -0
- data/README.md +436 -0
- data/Rakefile +101 -0
- data/examples/README.md +300 -0
- data/examples/drive_service_batch +72 -0
- data/examples/file_create +66 -0
- data/examples/file_create_folder +46 -0
- data/examples/file_create_spreadsheet +70 -0
- data/examples/file_delete +24 -0
- data/examples/file_download_content +27 -0
- data/examples/file_export_spreadsheet +48 -0
- data/examples/file_get +37 -0
- data/examples/file_recover_from_trash +24 -0
- data/examples/file_search +86 -0
- data/examples/file_send_to_trash +24 -0
- data/examples/file_upload_content +25 -0
- data/examples/permission_create +165 -0
- data/examples/permission_delete +22 -0
- data/examples/permission_list +49 -0
- data/examples/permission_update +134 -0
- data/lib/drive_v3/create_credential.rb +93 -0
- data/lib/drive_v3/version.rb +6 -0
- data/lib/drive_v3.rb +52 -0
- metadata +307 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Read the content of a data file
|
5
|
+
|
6
|
+
require 'drive_v3'
|
7
|
+
require 'json'
|
8
|
+
require 'stringio'
|
9
|
+
|
10
|
+
drive_service = DriveV3.drive_service
|
11
|
+
|
12
|
+
file_id = ARGV[0] || ENV.fetch('FILE_ID', nil)
|
13
|
+
raise 'Missing file_id' unless file_id
|
14
|
+
|
15
|
+
# download_dest can be an IO object that responds to `write` that will receive
|
16
|
+
# the content of the file, or a string naming an existing file to be written
|
17
|
+
# to.
|
18
|
+
download_dest = StringIO.new
|
19
|
+
|
20
|
+
# Read content from file
|
21
|
+
#
|
22
|
+
begin
|
23
|
+
drive_service.get_file(file_id, download_dest:)
|
24
|
+
puts JSON.pretty_generate(download_dest.string)
|
25
|
+
rescue StandardError => e
|
26
|
+
puts "An error occurred: #{e.message}"
|
27
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Export a spreadsheet to a .tsv file
|
5
|
+
#
|
6
|
+
# To export a specific sheet, use the sheet_id parameter. To export multiple
|
7
|
+
# sheets, use the sheet_ids parameter. Omitting the sheet_id parameter exports
|
8
|
+
# the first sheet.
|
9
|
+
#
|
10
|
+
# To export to a different file type, change the mimeType parameter.
|
11
|
+
|
12
|
+
require 'drive_v3'
|
13
|
+
require 'json'
|
14
|
+
|
15
|
+
drive_service = DriveV3.drive_service
|
16
|
+
|
17
|
+
# First create a spreadsheet, populating with some data.
|
18
|
+
# Then get the file id of the spreadsheet.
|
19
|
+
|
20
|
+
name = 'My Test Spreadsheet'
|
21
|
+
parents = [] # Create in the user's My Drive root folder
|
22
|
+
mime_type = 'application/vnd.google-apps.spreadsheet'
|
23
|
+
file_metadata = { name:, parents:, mime_type: }
|
24
|
+
fields = 'id, name'
|
25
|
+
upload_source = StringIO.new("1,2,3\n4,5,6\n7,8,9")
|
26
|
+
content_type = 'text/csv'
|
27
|
+
begin
|
28
|
+
file = drive_service.create_file(file_metadata, fields:, upload_source:, content_type:)
|
29
|
+
puts JSON.pretty_generate(file.to_h)
|
30
|
+
rescue StandardError => e
|
31
|
+
puts "An error occurred: #{e.message}"
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
# Export the spreadsheet to a PDF file nameed 'My Test Spreadsheet.pdf'
|
36
|
+
|
37
|
+
file_id = file.id
|
38
|
+
mime_type = 'application/pdf'
|
39
|
+
download_dest = "#{file.name}.pdf"
|
40
|
+
|
41
|
+
begin
|
42
|
+
drive_service.export_file(file_id, mime_type, download_dest:)
|
43
|
+
rescue StandardError => e
|
44
|
+
puts "An error occurred: #{e.message}"
|
45
|
+
exit 1
|
46
|
+
end
|
47
|
+
|
48
|
+
puts "Exported #{file.name} to #{download_dest}"
|
data/examples/file_get
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# `get_file` shows how to get a
|
5
|
+
# [File](https://github.com/googleapis/google-api-ruby-client/blob/main/generated/google-apis-drive_v3/lib/google/apis/drive_v3/classes.rb)
|
6
|
+
# from the drive controlling which fields are returned.
|
7
|
+
|
8
|
+
require 'drive_v3'
|
9
|
+
|
10
|
+
drive_service = DriveV3.drive_service
|
11
|
+
|
12
|
+
file_id = ARGV[0] || '1MNb_59W87lj75-9HqrEQoFBdrQiNl96rDlRy87sDIjs'
|
13
|
+
|
14
|
+
# If `fields` is not specified, the following fields are returned for each file:
|
15
|
+
# id, name, mimeType, and kind.
|
16
|
+
#
|
17
|
+
# Could return all possible fields by specifying `fields: '*'`. See
|
18
|
+
# [Return specific fields for a file](https://developers.google.com/drive/api/guides/fields-parameter)
|
19
|
+
# for more information about how to retrieve other fields.
|
20
|
+
#
|
21
|
+
# fields = 'id, name, parents, web_view_link'
|
22
|
+
fields = '*'
|
23
|
+
|
24
|
+
# If `supports_all_drives` is false or not specified, the request will fail if
|
25
|
+
# the file is in a shared drive.
|
26
|
+
#
|
27
|
+
# See [Search for files & folders](https://developers.google.com/drive/api/v3/search-files)
|
28
|
+
# for more information about how to search for files in shared drives.
|
29
|
+
#
|
30
|
+
supports_all_drives = true
|
31
|
+
|
32
|
+
begin
|
33
|
+
file = drive_service.get_file(file_id, fields:, supports_all_drives:)
|
34
|
+
puts JSON.pretty_generate(file.to_h)
|
35
|
+
rescue StandardError => e
|
36
|
+
puts "An error occurred: #{e.message}"
|
37
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# `recover_trashed_file` shows how to recover a file from the trash.
|
5
|
+
#
|
6
|
+
# Moving a file to the trash is done by updating the file's trashed attribute to
|
7
|
+
# true. To recover a trashed file is done by updating the file's trashed attribute
|
8
|
+
# to false.
|
9
|
+
|
10
|
+
require 'drive_v3'
|
11
|
+
|
12
|
+
drive_service = DriveV3.drive_service
|
13
|
+
|
14
|
+
file_id = ARGV[0] || ENV.fetch('FILE_ID', nil)
|
15
|
+
raise 'Missing file_id' unless file_id
|
16
|
+
|
17
|
+
begin
|
18
|
+
print 'Recovering trashed file...'
|
19
|
+
file_object = { trashed: false }
|
20
|
+
file = drive_service.update_file(file_id, file_object)
|
21
|
+
puts "update_file result:\n#{file.to_h.pretty_inspect}"
|
22
|
+
rescue StandardError => e
|
23
|
+
puts "An error occurred: #{e.message}"
|
24
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Search for files owned by the current user
|
5
|
+
#
|
6
|
+
# Returns a [FileList](https://github.com/googleapis/google-api-ruby-client/blob/main/generated/google-apis-drive_v3/lib/google/apis/drive_v3/classes.rb)
|
7
|
+
# object. The FileList object has a `files` property that is an array of files returned.
|
8
|
+
#
|
9
|
+
# This example illustrates how to:
|
10
|
+
# 1. specify a search query (to omit files in the trash)
|
11
|
+
# 2. specify which fields to return for each file
|
12
|
+
# 3. retrieve pagenated results
|
13
|
+
#
|
14
|
+
# Use the `jq` command to format the output of this script. For example:
|
15
|
+
# * List names: `bundle exec examples/list_files | jq '.[].name'`
|
16
|
+
# * List names and id's: `bundle exec examples/list_files | jq '[.[] | {name: .name, id: .id}]'`
|
17
|
+
# * List names and parents: `bundle exec examples/list_files | jq '[.[] | {name: .name, parents: .parents}]'`
|
18
|
+
|
19
|
+
require 'drive_v3'
|
20
|
+
|
21
|
+
@drive_service = DriveV3.drive_service
|
22
|
+
|
23
|
+
@parents = {}
|
24
|
+
|
25
|
+
def parent(id)
|
26
|
+
@parents[id] ||= @drive_service.get_file(id, fields: 'name, web_view_link')
|
27
|
+
end
|
28
|
+
|
29
|
+
files = []
|
30
|
+
|
31
|
+
# Number of files to return with each request
|
32
|
+
#
|
33
|
+
# Limiting to 5 for this example, normally this would be a lot higher
|
34
|
+
# (default is 100)
|
35
|
+
#
|
36
|
+
page_size = 100
|
37
|
+
|
38
|
+
# Signal to get first page of results
|
39
|
+
#
|
40
|
+
# nextPageToken property returns the page_token of the next page
|
41
|
+
# of results. If nextPageToken is empty, there are no more pages.
|
42
|
+
#
|
43
|
+
page_token = nil
|
44
|
+
|
45
|
+
# By default `list_files` returns all files even files in the trash. To omit trashed
|
46
|
+
# files add `trashed=false` to the q (query) parameter.
|
47
|
+
#
|
48
|
+
# See [Search for files & folders](https://developers.google.com/drive/api/v3/search-files)
|
49
|
+
# for more information about how to use the `q` parameter.
|
50
|
+
#
|
51
|
+
# q = "trashed=false and '1V6RS_7_YgJmLDH-BDw3dpD8Np60Oi9ET' in parents"
|
52
|
+
q = 'trashed=false'
|
53
|
+
|
54
|
+
# If `fields` is not specified, the following fields are returned for each file:
|
55
|
+
# id, name, mimeType, and kind.
|
56
|
+
#
|
57
|
+
# Could return all possible fields by specifying `fields: '*'`. In this example,
|
58
|
+
# we only need `nextPageToken` for the request and `id`, `name`, and `parents`,
|
59
|
+
# and `web_view_link` for each file.
|
60
|
+
#
|
61
|
+
# If you give fields, you must explicitly include `nextPageToken` if you want it.
|
62
|
+
#
|
63
|
+
# See [Return specific fields for a file](https://developers.google.com/drive/api/guides/fields-parameter)
|
64
|
+
# for more information about how to retrieve other fields.
|
65
|
+
#
|
66
|
+
# fields = 'nextPageToken, files(id, name, parents, web_view_link)'
|
67
|
+
fields = '*'
|
68
|
+
|
69
|
+
# If `include_items_from_all_drives` is false or omitted, only files from the user's
|
70
|
+
# default drive are returned.
|
71
|
+
#
|
72
|
+
include_items_from_all_drives = true
|
73
|
+
|
74
|
+
loop do
|
75
|
+
file_list = @drive_service.list_files(
|
76
|
+
q:, fields:, include_items_from_all_drives:,
|
77
|
+
page_token:, page_size:
|
78
|
+
)
|
79
|
+
files += file_list.files.map(&:to_h)
|
80
|
+
# Stop looping if there are no more pages
|
81
|
+
break unless (page_token = file_list.next_page_token)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Print as JSON with links to each file and its parents
|
85
|
+
|
86
|
+
puts JSON.pretty_generate(files)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# `trash_file` shows how to move a file to the trash.
|
5
|
+
#
|
6
|
+
# Moving a file to the trash is done by updating the file's trashed attribute to
|
7
|
+
# true. The process involves using the update method on the file you wish to move
|
8
|
+
# to the trash.
|
9
|
+
|
10
|
+
require 'drive_v3'
|
11
|
+
|
12
|
+
drive_service = DriveV3.drive_service
|
13
|
+
|
14
|
+
file_id = ARGV[0] || ENV.fetch('FILE_ID', nil)
|
15
|
+
raise 'Missing file_id' unless file_id
|
16
|
+
|
17
|
+
begin
|
18
|
+
print 'Trash file...'
|
19
|
+
file_object = { trashed: true }
|
20
|
+
file = drive_service.update_file(file_id, file_object)
|
21
|
+
puts "update_file result:\n#{file.to_h.pretty_inspect}"
|
22
|
+
rescue StandardError => e
|
23
|
+
puts "An error occurred: #{e.message}"
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Replace a file's content
|
5
|
+
|
6
|
+
require 'drive_v3'
|
7
|
+
|
8
|
+
drive_service = DriveV3.drive_service
|
9
|
+
|
10
|
+
file_id = ARGV[0] || ENV.fetch('FILE_ID', nil)
|
11
|
+
raise 'Missing file_id' unless file_id
|
12
|
+
|
13
|
+
# upload_source can be an IO object that responds to `read` and `size` (e.g.
|
14
|
+
# StringIO) or a string that names an existing file to upload.
|
15
|
+
#
|
16
|
+
upload_source = StringIO.new('This is the content that replaced the original content')
|
17
|
+
|
18
|
+
# Replace the content of an existing file
|
19
|
+
#
|
20
|
+
begin
|
21
|
+
file = drive_service.update_file(file_id, upload_source:)
|
22
|
+
puts JSON.pretty_generate(file.to_h)
|
23
|
+
rescue StandardError => e
|
24
|
+
puts "An error occurred: #{e.message}"
|
25
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Creates a new permission for a file
|
5
|
+
#
|
6
|
+
# To add a permission:
|
7
|
+
#
|
8
|
+
# 1. Create a permission object with the `type` and `role`. If type=user or
|
9
|
+
# type=group, provide an `email_address`. If type=domain, provide a `domain`.
|
10
|
+
# 2. Call the `create_permission` method with the id for the associated file
|
11
|
+
# or folder.
|
12
|
+
# 3. The response returns an instance of a Permission resource, including the
|
13
|
+
# assigned id.
|
14
|
+
|
15
|
+
require 'drive_v3'
|
16
|
+
require 'optparse'
|
17
|
+
|
18
|
+
# Parse the command line
|
19
|
+
#
|
20
|
+
# @example For a user or group
|
21
|
+
# permission-create FILE_ID \
|
22
|
+
# --type {user|group} \
|
23
|
+
# --email EMAIL \
|
24
|
+
# --role ROLE \
|
25
|
+
# [--expiration TIME] \
|
26
|
+
# [{--allow-file-discovery | --no-allow-file-discovery}]
|
27
|
+
#
|
28
|
+
# @example For a domain
|
29
|
+
# permission-create FILE_ID \
|
30
|
+
# --type domain \
|
31
|
+
# --domain NAME \
|
32
|
+
# --role ROLE \
|
33
|
+
# [--expiration TIME] \
|
34
|
+
# [{--allow-file-discovery | --no-allow-file-discovery}]
|
35
|
+
#
|
36
|
+
# @example For a anyone
|
37
|
+
# permission-create FILE_ID \
|
38
|
+
# --type anyone \
|
39
|
+
# --role ROLE \
|
40
|
+
# [--expiration TIME] \
|
41
|
+
# [{--allow-file-discovery | --no-allow-file-discovery}]
|
42
|
+
#
|
43
|
+
class PermissionCreateCli
|
44
|
+
def initialize(argv)
|
45
|
+
@argv = argv.dup
|
46
|
+
default_options
|
47
|
+
parser.parse!(@argv)
|
48
|
+
@file_id = @argv.shift || ENV.fetch('FILE_ID', nil)
|
49
|
+
validate(@argv)
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_reader :file_id, :permission_id, :permission
|
53
|
+
|
54
|
+
def to_s
|
55
|
+
"'#{file_id}', #{permission}"
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def banner = <<~BANNER
|
61
|
+
Usage:
|
62
|
+
#{$PROGRAM_NAME} FILE_ID [options]
|
63
|
+
|
64
|
+
Creates permission for a file.
|
65
|
+
|
66
|
+
Options:
|
67
|
+
BANNER
|
68
|
+
|
69
|
+
def parser
|
70
|
+
@parser ||= OptionParser.new(banner) do |opts|
|
71
|
+
option_definitions.each { |option_definition| opts.on(*option_definition) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def help
|
76
|
+
puts parser
|
77
|
+
exit
|
78
|
+
end
|
79
|
+
|
80
|
+
def option_definitions
|
81
|
+
[
|
82
|
+
help_definition,
|
83
|
+
type_definition, email_definition, domain_definition, role_definition,
|
84
|
+
allow_file_discovery_definition, expiration_definition
|
85
|
+
].freeze
|
86
|
+
end
|
87
|
+
|
88
|
+
def help_definition = ['-h', '--help', '', ->(_value) { help }]
|
89
|
+
def type_definition = ['--type=TYPE', ->(value) { @permission[:type] = value }]
|
90
|
+
def email_definition = ['--email=EMAIL', ->(value) { @permission[:email_address] = value }]
|
91
|
+
def domain_definition = ['--domain=DOMAIN', ->(value) { @permission[:domain] = value }]
|
92
|
+
def role_definition = ['--role=ROLE', ->(value) { @permission[:role] = value }]
|
93
|
+
|
94
|
+
def allow_file_discovery_definition
|
95
|
+
[
|
96
|
+
'--[no-]allow-file-discovery',
|
97
|
+
->(value) { @permission[:allow_file_discovery] = value }
|
98
|
+
]
|
99
|
+
end
|
100
|
+
|
101
|
+
def expiration_definition
|
102
|
+
[
|
103
|
+
'--expiration=TIME',
|
104
|
+
->(value) { @permission[:expiration_time] = DateTime.parse(value) }
|
105
|
+
]
|
106
|
+
end
|
107
|
+
|
108
|
+
def default_options
|
109
|
+
@file_id = nil
|
110
|
+
@permission = {
|
111
|
+
type: nil, email_address: nil, domain: nil, role: nil,
|
112
|
+
allow_file_discovery: nil, expiration_time: nil
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
def validate(argv)
|
117
|
+
raise "Extra command line arguments: #{argv}" unless argv.empty?
|
118
|
+
|
119
|
+
raise 'Missing file_id' unless file_id
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# The new permission to create
|
124
|
+
#
|
125
|
+
# `type` can be user, group, domain, or anyone.
|
126
|
+
#
|
127
|
+
# When type=user or type=group, you must also provide an `email_address`.
|
128
|
+
#
|
129
|
+
# When type=domain, you must also provide a `domain``.
|
130
|
+
#
|
131
|
+
# See [Share files, folders & drives](https://developers.google.com/drive/api/guides/manage-sharing)
|
132
|
+
#
|
133
|
+
# See [Roles & permissions](https://developers.google.com/drive/api/guides/ref-roles)
|
134
|
+
# for more information about the different roles.
|
135
|
+
#
|
136
|
+
# allow_file_discovery is not valid for individual users.
|
137
|
+
#
|
138
|
+
# @example: when type is 'anyone'
|
139
|
+
# permission = {
|
140
|
+
# allow_file_discovery: true,
|
141
|
+
# type: 'anyone',
|
142
|
+
# role: 'writer'
|
143
|
+
# }
|
144
|
+
#
|
145
|
+
# @example: when type is 'user'
|
146
|
+
# permission = {
|
147
|
+
# type: 'user',
|
148
|
+
# role: 'writer',
|
149
|
+
# email_address: 'jcouball@gmail.com'
|
150
|
+
# }
|
151
|
+
#
|
152
|
+
|
153
|
+
drive_service = DriveV3.drive_service
|
154
|
+
|
155
|
+
options = PermissionCreateCli.new(ARGV)
|
156
|
+
fields = '*'
|
157
|
+
|
158
|
+
begin
|
159
|
+
result = drive_service.create_permission(options.file_id, options.permission, fields:)
|
160
|
+
# The result.id is 'anyoneWithLink' if type=anyone
|
161
|
+
# The result.id is of the existing permission if it already exists
|
162
|
+
puts JSON.pretty_generate(result.to_h)
|
163
|
+
rescue StandardError => e
|
164
|
+
puts "An error occurred: #{e.message}"
|
165
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# List permissions for a file or folder
|
5
|
+
|
6
|
+
require 'drive_v3'
|
7
|
+
|
8
|
+
file_id = ARGV.shift || ENV.fetch('FILE_ID', nil)
|
9
|
+
raise 'Missing file_id' unless file_id
|
10
|
+
|
11
|
+
permission_id = ARGV.shift || ENV.fetch('PERMISSION_ID', nil)
|
12
|
+
raise 'Missing permission_id' unless permission_id
|
13
|
+
|
14
|
+
raise "Extra arguments: #{ARGV}" unless ARGV.empty?
|
15
|
+
|
16
|
+
drive_service = DriveV3.drive_service
|
17
|
+
|
18
|
+
begin
|
19
|
+
drive_service.delete_permission(file_id, permission_id)
|
20
|
+
rescue StandardError => e
|
21
|
+
puts "An error occurred: #{e.message}"
|
22
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# List permissions for a file or folder
|
5
|
+
|
6
|
+
require 'drive_v3'
|
7
|
+
|
8
|
+
file_id = ARGV[0] || ENV.fetch('FILE_ID', nil)
|
9
|
+
raise 'Missing file_id' unless file_id
|
10
|
+
|
11
|
+
drive_service = DriveV3.drive_service
|
12
|
+
|
13
|
+
permissions = []
|
14
|
+
|
15
|
+
# Number of files to return with each request
|
16
|
+
#
|
17
|
+
# Limiting to 2 for this example, normally this would be a lot higher
|
18
|
+
# (default is 100)
|
19
|
+
#
|
20
|
+
page_size = 2
|
21
|
+
|
22
|
+
# Signal to get first page of results
|
23
|
+
#
|
24
|
+
# nextPageToken property returns the page_token of the next page
|
25
|
+
# of results. If nextPageToken is empty, there are no more pages.
|
26
|
+
#
|
27
|
+
page_token = nil
|
28
|
+
|
29
|
+
# If `fields` is not specified, the following fields are returned for each permission:
|
30
|
+
# ???
|
31
|
+
#
|
32
|
+
# Could return all possible fields by specifying `fields: '*'`.
|
33
|
+
#
|
34
|
+
# If you give fields, you must explicitly include `nextPageToken` if you want it.
|
35
|
+
#
|
36
|
+
# See [Return specific fields for a file](https://developers.google.com/drive/api/guides/fields-parameter)
|
37
|
+
# for more information about how to retrieve other fields.
|
38
|
+
#
|
39
|
+
# fields = 'nextPageToken, files(id, name, parents, web_view_link)'
|
40
|
+
fields = '*'
|
41
|
+
|
42
|
+
loop do
|
43
|
+
permission_list = drive_service.list_permissions(file_id, fields:, page_token:, page_size:)
|
44
|
+
permissions += permission_list.permissions.map(&:to_h)
|
45
|
+
# Stop looping if there are no more pages
|
46
|
+
break unless (page_token = permission_list.next_page_token)
|
47
|
+
end
|
48
|
+
|
49
|
+
puts JSON.pretty_generate(permissions)
|
@@ -0,0 +1,134 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Updates an existing permission for a file
|
5
|
+
#
|
6
|
+
# Use permission_list to list the existing permissions for a file.
|
7
|
+
|
8
|
+
require 'drive_v3'
|
9
|
+
require 'optparse'
|
10
|
+
require 'time'
|
11
|
+
|
12
|
+
# Parse command line arguments
|
13
|
+
#
|
14
|
+
# Usage: permission-update FILE_ID PERMISSION_ID \
|
15
|
+
# --remove-expiration \
|
16
|
+
# --type TYPE \
|
17
|
+
# --email EMAIL \
|
18
|
+
# --domain DOMAIN \
|
19
|
+
# --role ROLE \
|
20
|
+
# --[no-]allow-file-discovery \
|
21
|
+
# --expiration TIME
|
22
|
+
#
|
23
|
+
# Examples:
|
24
|
+
# permission-update 12345678 12345678 --expiration 2023-12-31T00:00:00-07:00
|
25
|
+
# permission-update 12345678 12345678 --remove-expiration
|
26
|
+
# permission-update 12345678 12345678 --role reader
|
27
|
+
# permission-update 12345678 12345678 --email jcouball@yahoo.com
|
28
|
+
# permission-update 12345678 12345678 --email jcouball@yahoo.com --role reader
|
29
|
+
# permission-update 12345678 12345678 --allow-file-discovery
|
30
|
+
# permission-update 12345678 12345678 --no-allow-file-discovery
|
31
|
+
#
|
32
|
+
class PermissionUpdateCli
|
33
|
+
def initialize(argv)
|
34
|
+
@argv = argv.dup
|
35
|
+
default_options
|
36
|
+
parser.parse!(@argv)
|
37
|
+
@file_id = @argv.shift || ENV.fetch('FILE_ID', nil)
|
38
|
+
@permission_id = @argv.shift || ENV.fetch('PERMISSION_ID', nil)
|
39
|
+
validate(@argv)
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader :file_id, :permission_id, :permission, :remove_expiration
|
43
|
+
|
44
|
+
def to_s
|
45
|
+
"'#{file_id}', '#{permission_id}', #{permission}, remove_expiration: #{remove_expiration}"
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def banner = <<~BANNER
|
51
|
+
Usage:
|
52
|
+
#{$PROGRAM_NAME} FILE_ID PERMISSION_ID [options]
|
53
|
+
|
54
|
+
Updates a permission for a file.
|
55
|
+
Use permission-create to create a new permission for a file.
|
56
|
+
User permission-list to list permissions for a file.
|
57
|
+
|
58
|
+
Options:
|
59
|
+
BANNER
|
60
|
+
|
61
|
+
def parser
|
62
|
+
@parser ||= OptionParser.new(banner) do |opts|
|
63
|
+
option_definitions.each { |option_definition| opts.on(*option_definition) }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def help
|
68
|
+
puts parser
|
69
|
+
exit
|
70
|
+
end
|
71
|
+
|
72
|
+
def option_definitions
|
73
|
+
[
|
74
|
+
help_definition, remove_expiration_definition, type_definition,
|
75
|
+
email_definition, domain_definition, role_definition,
|
76
|
+
allow_file_discovery_definition, expiration_definition
|
77
|
+
].freeze
|
78
|
+
end
|
79
|
+
|
80
|
+
def help_definition = ['-h', '--help', '', ->(_value) { help }]
|
81
|
+
def type_definition = ['--type=TYPE', ->(value) { @permission[:type] = value }]
|
82
|
+
def email_definition = ['--email=EMAIL', ->(value) { @permission[:email_address] = value }]
|
83
|
+
def domain_definition = ['--domain=DOMAIN', ->(value) { @permission[:domain] = value }]
|
84
|
+
def role_definition = ['--role=ROLE', ->(value) { @permission[:role] = value }]
|
85
|
+
def remove_expiration_definition = ['--remove-expiration', ->(_value) { @remove_expiration = true }]
|
86
|
+
|
87
|
+
def allow_file_discovery_definition
|
88
|
+
[
|
89
|
+
'--[no-]allow-file-discovery',
|
90
|
+
->(value) { @permission[:allow_file_discovery] = value }
|
91
|
+
]
|
92
|
+
end
|
93
|
+
|
94
|
+
def expiration_definition
|
95
|
+
[
|
96
|
+
'--expiration=TIME',
|
97
|
+
->(value) { @permission[:expiration_time] = DateTime.parse(value) }
|
98
|
+
]
|
99
|
+
end
|
100
|
+
|
101
|
+
def default_options
|
102
|
+
@file_id = nil
|
103
|
+
@permission_id = nil
|
104
|
+
@permission = {
|
105
|
+
type: nil, email_address: nil, domain: nil, role: nil,
|
106
|
+
allow_file_discovery: nil, expiration_time: nil
|
107
|
+
}
|
108
|
+
@remove_expiration = nil
|
109
|
+
end
|
110
|
+
|
111
|
+
def validate(argv)
|
112
|
+
raise "Extra command line arguments: #{argv}" unless argv.empty?
|
113
|
+
|
114
|
+
raise 'Missing file_id' unless file_id
|
115
|
+
|
116
|
+
raise 'Missing permission_id' unless permission_id
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
drive_service = DriveV3.drive_service
|
121
|
+
|
122
|
+
options = PermissionUpdateCli.new(ARGV)
|
123
|
+
file_id = options.file_id
|
124
|
+
permission_id = options.permission_id
|
125
|
+
permission = options.permission
|
126
|
+
remove_expiration = options.remove_expiration
|
127
|
+
fields = '*'
|
128
|
+
|
129
|
+
begin
|
130
|
+
result = drive_service.update_permission(file_id, permission_id, permission, remove_expiration:, fields:)
|
131
|
+
puts "Permission updated: #{result.to_h.pretty_inspect}"
|
132
|
+
rescue StandardError => e
|
133
|
+
puts "An error occurred: #{e.message}"
|
134
|
+
end
|