google_drive 1.0.6 → 2.0.0.pre1

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.
@@ -4,34 +4,32 @@
4
4
  require 'json'
5
5
 
6
6
  module GoogleDrive
7
- class Config #:nodoc:
8
-
9
- FIELDS = %w(client_id client_secret scope refresh_token).freeze
10
- attr_accessor(*FIELDS)
11
-
12
- def initialize(config_path)
13
- @config_path = config_path
14
- if ::File.exist?(config_path)
15
- JSON.parse(::File.read(config_path)).each do |key, value|
16
- instance_variable_set("@#{key}", value) if FIELDS.include?(key)
17
- end
18
- end
19
- end
20
-
21
- def save
22
- ::File.open(@config_path, 'w', 0600) { |f| f.write(to_json()) }
7
+ class Config #:nodoc:
8
+ FIELDS = %w(client_id client_secret scope refresh_token).freeze
9
+ attr_accessor(*FIELDS)
10
+
11
+ def initialize(config_path)
12
+ @config_path = config_path
13
+ if ::File.exist?(config_path)
14
+ JSON.parse(::File.read(config_path)).each do |key, value|
15
+ instance_variable_set("@#{key}", value) if FIELDS.include?(key)
23
16
  end
17
+ end
18
+ end
24
19
 
25
- private
20
+ def save
21
+ ::File.open(@config_path, 'w', 0600) { |f| f.write(to_json) }
22
+ end
26
23
 
27
- def to_json
28
- hash = {}
29
- FIELDS.each do |field|
30
- value = __send__(field)
31
- hash[field] = value if value
32
- end
33
- return JSON.pretty_generate(hash)
34
- end
24
+ private
35
25
 
26
+ def to_json
27
+ hash = {}
28
+ FIELDS.each do |field|
29
+ value = __send__(field)
30
+ hash[field] = value if value
31
+ end
32
+ JSON.pretty_generate(hash)
36
33
  end
34
+ end
37
35
  end
@@ -2,7 +2,7 @@
2
2
  # The license of this source is "New BSD Licence"
3
3
 
4
4
  module GoogleDrive
5
- # Raised on errors in this library.
6
- class Error < RuntimeError
7
- end
5
+ # Raised on errors in this library.
6
+ class Error < RuntimeError
7
+ end
8
8
  end
@@ -1,301 +1,243 @@
1
1
  # Author: Hiroshi Ichikawa <http://gimite.net/>
2
2
  # The license of this source is "New BSD Licence"
3
3
 
4
- require "cgi"
5
- require "forwardable"
6
- require "stringio"
7
-
8
- require "google_drive/util"
9
- require "google_drive/acl"
4
+ require 'cgi'
5
+ require 'forwardable'
6
+ require 'stringio'
10
7
 
8
+ require 'google_drive/util'
9
+ require 'google_drive/acl'
11
10
 
12
11
  module GoogleDrive
13
-
14
- # A file in Google Drive, including Google Docs document/spreadsheet/presentation.
12
+ # A file in Google Drive, including Google Docs document/spreadsheet/presentation.
13
+ #
14
+ # Use GoogleDrive::Session#files or GoogleDrive::Session#file_by_title to
15
+ # get this object.
16
+ #
17
+ # In addition to the methods below, properties defined here are also available as attributes:
18
+ # https://developers.google.com/drive/v3/reference/files#resource
19
+ #
20
+ # e.g.,
21
+ # file.mime_type # ==> "text/plain"
22
+ class File
23
+ include(Util)
24
+ extend(Forwardable)
25
+
26
+ def initialize(session, api_file) #:nodoc:
27
+ @session = session
28
+ @api_file = api_file
29
+ @acl = nil
30
+ delegate_api_methods(self, @api_file, [:title])
31
+ end
32
+
33
+ # Wrapped Google::APIClient::Schema::Drive::V3::File object.
34
+ attr_reader(:api_file)
35
+
36
+ # Reloads file metadata such as title and acl.
37
+ def reload_metadata
38
+ @api_file = @session.drive.get_file(id, fields: '*')
39
+ @acl = Acl.new(@session, self) if @acl
40
+ end
41
+
42
+ # Returns resource_type + ":" + id.
43
+ def resource_id
44
+ '%s:%s' % [resource_type, id]
45
+ end
46
+
47
+ # URL of feed used in the deprecated document list feed API.
48
+ def document_feed_url
49
+ 'https://docs.google.com/feeds/default/private/full/' + CGI.escape(resource_id)
50
+ end
51
+
52
+ # Deprecated ACL feed URL of the file.
53
+ def acl_feed_url
54
+ document_feed_url + '/acl'
55
+ end
56
+
57
+ # The type of resourse. e.g. "document", "spreadsheet", "folder"
58
+ def resource_type
59
+ mime_type.slice(/^application\/vnd.google-apps.(.+)$/, 1) || 'file'
60
+ end
61
+
62
+ # Title of the file.
63
+ def title(params = {})
64
+ reload_metadata if params[:reload]
65
+ api_file.name
66
+ end
67
+
68
+ # URL to view/edit the file in a Web browser.
15
69
  #
16
- # Use GoogleDrive::Session#files or GoogleDrive::Session#file_by_title to
17
- # get this object.
70
+ # e.g. "https://docs.google.com/file/d/xxxx/edit"
71
+ def human_url
72
+ api_file.web_view_link
73
+ end
74
+
75
+ # Content types you can specify in methods download_to_file, download_to_string,
76
+ # download_to_io .
18
77
  #
19
- # In addition to the methods below, properties defined here are also available as attributes:
20
- # https://developers.google.com/drive/v2/reference/files#resource
78
+ # This returns zero or one file type. You may be able to download the file in other formats using
79
+ # export_as_file, export_as_string, or export_to_io.
80
+ def available_content_types
81
+ api_file.download_url ? [api_file.mime_type] : []
82
+ end
83
+
84
+ # Downloads the file to a local file. e.g.
85
+ # file.download_to_file("/path/to/hoge.txt")
21
86
  #
22
- # e.g.,
23
- # file.mime_type # ==> "text/plain"
24
- class File
87
+ # To export the file in other formats, use export_as_file.
88
+ def download_to_file(path, params = {})
89
+ @session.drive.get_file(id, download_dest: path)
90
+ end
25
91
 
26
- include(Util)
27
- extend(Forwardable)
28
-
29
- def initialize(session, api_file) #:nodoc:
30
- @session = session
31
- @api_file = api_file
32
- @acl = nil
33
- delegate_api_methods(self, @api_file, ["title"])
34
- end
92
+ # Downloads the file and returns as a String.
93
+ #
94
+ # To export the file in other formats, use export_as_string.
95
+ def download_to_string(params = {})
96
+ sio = StringIO.new
97
+ download_to_io(sio, params)
98
+ sio.string
99
+ end
35
100
 
36
- # Wrapped Google::APIClient::Schema::Drive::V2::File object.
37
- attr_reader(:api_file)
101
+ # Downloads the file and writes it to +io+.
102
+ #
103
+ # To export the file in other formats, use export_to_io.
104
+ def download_to_io(io, _params = {})
105
+ @session.drive.get_file(id, download_dest: io)
106
+ end
38
107
 
39
- # Reloads file metadata such as title and acl.
40
- def reload_metadata()
41
- api_result = @session.execute!(
42
- :api_method => @session.drive.files.get,
43
- :parameters => { "fileId" => self.id })
44
- @api_file = api_result.data
45
- if @acl
46
- @acl = Acl.new(@session, self)
47
- end
48
- end
108
+ # Export the file to +path+ in content type +format+.
109
+ # If +format+ is nil, it is guessed from the file name.
110
+ #
111
+ # e.g.,
112
+ # spreadsheet.export_as_file("/path/to/hoge.csv")
113
+ # spreadsheet.export_as_file("/path/to/hoge", "text/csv")
114
+ #
115
+ # If you want to download the file in the original format, use download_to_file instead.
116
+ def export_as_file(path, format = nil)
117
+ unless format
118
+ format = EXT_TO_CONTENT_TYPE[::File.extname(path).downcase]
119
+ unless format
120
+ fail(ArgumentError,
121
+ ("Cannot guess format from the file name: %s\n" \
122
+ 'Specify format argument explicitly.') %
123
+ path)
124
+ end
125
+ end
126
+ export_to_dest(path, format)
127
+ end
49
128
 
50
- # Returns resource_type + ":" + id.
51
- def resource_id
52
- return "%s:%s" % [self.resource_type, self.id]
53
- end
129
+ # Export the file as String in content type +format+.
130
+ #
131
+ # e.g.,
132
+ # spreadsheet.export_as_string("text/csv")
133
+ #
134
+ # If you want to download the file in the original format, use download_to_string instead.
135
+ def export_as_string(format)
136
+ sio = StringIO.new
137
+ export_to_dest(sio, format)
138
+ sio.string
139
+ end
54
140
 
55
- # URL of feed used in the deprecated document list feed API.
56
- def document_feed_url
57
- return "https://docs.google.com/feeds/default/private/full/" + CGI.escape(self.resource_id)
58
- end
141
+ # Export the file to +io+ in content type +format+.
142
+ #
143
+ # If you want to download the file in the original format, use download_to_io instead.
144
+ def export_to_io(io, format)
145
+ export_to_dest(io, format)
146
+ end
59
147
 
60
- # Deprecated ACL feed URL of the file.
61
- def acl_feed_url
62
- return self.document_feed_url + "/acl"
63
- end
148
+ # Updates the file with +content+.
149
+ #
150
+ # e.g.
151
+ # file.update_from_string("Good bye, world.")
152
+ def update_from_string(content, params = {})
153
+ update_from_io(StringIO.new(content), params)
154
+ end
64
155
 
65
- # The type of resourse. e.g. "document", "spreadsheet", "folder"
66
- def resource_type
67
- return self.mime_type.slice(/^application\/vnd.google-apps.(.+)$/, 1) || "file"
68
- end
156
+ # Updates the file with the content of the local file.
157
+ #
158
+ # e.g.
159
+ # file.update_from_file("/path/to/hoge.txt")
160
+ def update_from_file(path, params = {})
161
+ # Somehow it doesn't work if I specify the file name directly as upload_source.
162
+ open(path, 'rb') do |f|
163
+ update_from_io(f, params)
164
+ end
165
+ nil
166
+ end
69
167
 
70
- # Title of the file.
71
- def title(params = {})
72
- reload_metadata() if params[:reload]
73
- return self.api_file.title
74
- end
75
-
76
- # URL to view/edit the file in a Web browser.
77
- #
78
- # e.g. "https://docs.google.com/file/d/xxxx/edit"
79
- def human_url
80
- return self.alternate_link
81
- end
82
-
83
- # Content types you can specify in methods download_to_file, download_to_string,
84
- # download_to_io .
85
- #
86
- # This returns zero or one file type. You may be able to download the file in other formats using
87
- # export_as_file, export_as_string, or export_to_io. Use export_links method to get available formats
88
- # in these methods.
89
- def available_content_types
90
- if self.api_file.download_url
91
- return [self.api_file.mime_type]
92
- else
93
- return []
94
- end
95
- end
96
-
97
- # Downloads the file to a local file. e.g.
98
- # file.download_to_file("/path/to/hoge.txt")
99
- #
100
- # To export the file in other formats, use export_as_file.
101
- def download_to_file(path, params = {})
102
- open(path, "wb") do |f|
103
- download_to_io(f, params)
104
- end
105
- end
106
-
107
- # Downloads the file and returns as a String.
108
- #
109
- # To export the file in other formats, use export_as_string.
110
- def download_to_string(params = {})
111
- sio = StringIO.new()
112
- download_to_io(sio, params)
113
- return sio.string
114
- end
115
-
116
- # Downloads the file and writes it to +io+.
117
- #
118
- # To export the file in other formats, use export_to_io.
119
- def download_to_io(io, params = {})
120
- if !self.api_file.download_url
121
- raise(GoogleDrive::Error, "Downloading is not supported for this file.")
122
- end
123
- # TODO Use streaming if possible.
124
- api_result = @session.execute!(:uri => self.api_file.download_url)
125
- io.write(api_result.body)
126
- end
168
+ # Reads content from +io+ and updates the file with the content.
169
+ def update_from_io(io, params = {})
170
+ params = { upload_source: io }.merge(params)
171
+ @session.drive.update_file(id, nil, params)
172
+ nil
173
+ end
127
174
 
128
- # Export the file to +path+ in content type +format+.
129
- # If +format+ is nil, it is guessed from the file name.
130
- #
131
- # e.g.,
132
- # spreadsheet.export_as_file("/path/to/hoge.csv")
133
- # spreadsheet.export_as_file("/path/to/hoge", "text/csv")
134
- #
135
- # If you want to download the file in the original format, use download_to_file instead.
136
- def export_as_file(path, format = nil)
137
- if !format
138
- format = EXT_TO_CONTENT_TYPE[::File.extname(path).downcase]
139
- if !format
140
- raise(ArgumentError,
141
- ("Cannot guess format from the file name: %s\n" +
142
- "Specify format argument explicitly.") %
143
- path)
144
- end
145
- end
146
- open(path, "wb") do |f|
147
- export_to_io(f, format)
148
- end
149
- end
150
-
151
- # Export the file as String in content type +format+.
152
- #
153
- # e.g.,
154
- # spreadsheet.export_as_string("text/csv")
155
- #
156
- # If you want to download the file in the original format, use download_to_string instead.
157
- def export_as_string(format)
158
- sio = StringIO.new()
159
- export_to_io(sio, format)
160
- return sio.string
161
- end
175
+ # If +permanent+ is +false+, moves the file to the trash.
176
+ # If +permanent+ is +true+, deletes the file permanently.
177
+ def delete(permanent = false)
178
+ if permanent
179
+ @session.drive.delete_file(id)
180
+ else
181
+ @session.drive.update_file(id, { trashed: true }, {})
182
+ end
183
+ nil
184
+ end
162
185
 
163
- # Export the file to +io+ in content type +format+.
164
- #
165
- # If you want to download the file in the original format, use download_to_io instead.
166
- def export_to_io(io, format)
167
- mime_type = EXT_TO_CONTENT_TYPE["." + format] || format
168
- if !self.export_links
169
- raise(
170
- GoogleDrive::Error,
171
- "This file doesn't support exporting. You may still download the file in the " +
172
- "original format using download_to_file, download_to_string or download_to_io.")
173
- end
174
- export_url = self.export_links[mime_type]
175
- if !export_url
176
- raise(
177
- GoogleDrive::Error,
178
- "This file doesn't support export with mime type %p. Supported mime types: %p" %
179
- [mime_type, self.export_links.to_hash().keys])
180
- end
181
- # TODO Use streaming if possible.
182
- api_result = @session.execute!(:uri => export_url)
183
- io.write(api_result.body)
184
- end
185
-
186
- # Updates the file with +content+.
187
- #
188
- # e.g.
189
- # file.update_from_string("Good bye, world.")
190
- def update_from_string(content, params = {})
191
- media = new_upload_io(StringIO.new(content), params)
192
- return update_from_media(media, params)
193
- end
194
-
195
- # Updates the file with the content of the local file.
196
- #
197
- # e.g.
198
- # file.update_from_file("/path/to/hoge.txt")
199
- def update_from_file(path, params = {})
200
- file_name = ::File.basename(path)
201
- params = {:file_name => file_name}.merge(params)
202
- media = new_upload_io(path, params)
203
- return update_from_media(media, params)
204
- end
186
+ # Renames title of the file.
187
+ def rename(title)
188
+ @session.drive.update_file(id, { name: title }, {})
189
+ nil
190
+ end
205
191
 
206
- # Reads content from +io+ and updates the file with the content.
207
- def update_from_io(io, params = {})
208
- media = new_upload_io(io, params)
209
- return update_from_media(media, params)
210
- end
192
+ alias_method :title=, :rename
211
193
 
212
- # Reads content from +media+ and updates the file with the content.
213
- def update_from_media(media, params = {})
214
- api_result = @session.execute!(
215
- :api_method => @session.drive.files.update,
216
- :media => media,
217
- :parameters => {
218
- "fileId" => self.id,
219
- "uploadType" => "media",
220
- })
221
- return @session.wrap_api_file(api_result.data)
222
- end
194
+ # Creates copy of this file with the given title.
195
+ def copy(title)
196
+ api_file = @session.drive.copy_file(id, { name: title }, {})
197
+ @session.wrap_api_file(api_file)
198
+ end
223
199
 
224
- # If +permanent+ is +false+, moves the file to the trash.
225
- # If +permanent+ is +true+, deletes the file permanently.
226
- def delete(permanent = false)
227
- if permanent
228
- @session.execute!(
229
- :api_method => @session.drive.files.delete,
230
- :parameters => {"fileId" => self.id})
231
- else
232
- @session.execute!(
233
- :api_method => @session.drive.files.trash,
234
- :parameters => {"fileId" => self.id})
235
- end
236
- return nil
237
- end
200
+ alias_method :duplicate, :copy
238
201
 
239
- # Renames title of the file.
240
- def rename(title)
241
- api_result = @session.execute!(
242
- :api_method => @session.drive.files.patch,
243
- :body_object => {"title" => title},
244
- :parameters => {"fileId" => self.id})
245
- @api_file = api_result.data
246
- end
247
-
248
- alias title= rename
202
+ # Returns GoogleDrive::Acl object for the file.
203
+ #
204
+ # With the object, you can see and modify people who can access the file.
205
+ # Modifications take effect immediately.
206
+ #
207
+ # e.g.
208
+ # # Dumps people who have access:
209
+ # for entry in file.acl
210
+ # p [entry.type, entry.email_address, entry.role]
211
+ # # => e.g. ["user", "example1@gmail.com", "owner"]
212
+ # end
213
+ #
214
+ # # Shares the file with new people:
215
+ # # NOTE: This sends email to the new people.
216
+ # file.acl.push(
217
+ # {type: "user", email_address: "example2@gmail.com", role: "reader"})
218
+ # file.acl.push(
219
+ # {type: "user", email_address: "example3@gmail.com", role: "writer"})
220
+ #
221
+ # # Changes the role of a person:
222
+ # file.acl[1].role = "writer"
223
+ #
224
+ # # Deletes an ACL entry:
225
+ # file.acl.delete(file.acl[1])
226
+ def acl(params = {})
227
+ @acl = Acl.new(@session, self) if !@acl || params[:reload]
228
+ @acl
229
+ end
249
230
 
250
- # Creates copy of this file with the given title.
251
- def copy(title)
252
- copied_file = @session.drive.files.copy.request_schema.new({
253
- "title" => title,
254
- })
255
- api_result = @session.execute!(
256
- :api_method => @session.drive.files.copy,
257
- :body_object => copied_file,
258
- :parameters => {"fileId" => self.id})
259
- return @session.wrap_api_file(api_result.data)
260
- end
231
+ def inspect
232
+ "\#<%p id=%p title=%p>" % [self.class, id, title]
233
+ end
261
234
 
262
- alias duplicate copy
263
-
264
- # Returns GoogleDrive::Acl object for the file.
265
- #
266
- # With the object, you can see and modify people who can access the file.
267
- # Modifications take effect immediately.
268
- #
269
- # e.g.
270
- # # Dumps people who have access:
271
- # for entry in file.acl
272
- # p [entry.scope_type, entry.scope, entry.role]
273
- # # => e.g. ["user", "example1@gmail.com", "owner"]
274
- # end
275
- #
276
- # # Shares the file with new people:
277
- # # NOTE: This sends email to the new people.
278
- # file.acl.push(
279
- # {:type => "user", :value => "example2@gmail.com", :role => "reader"})
280
- # file.acl.push(
281
- # {:type => "user", :value => "example3@gmail.com", :role => "writer"})
282
- #
283
- # # Changes the role of a person:
284
- # file.acl[1].role = "writer"
285
- #
286
- # # Deletes an ACL entry:
287
- # file.acl.delete(file.acl[1])
288
- def acl(params = {})
289
- if !@acl || params[:reload]
290
- @acl = Acl.new(@session, self)
291
- end
292
- return @acl
293
- end
235
+ private
294
236
 
295
- def inspect
296
- return "\#<%p id=%p title=%p>" % [self.class, self.id, self.title]
297
- end
298
-
237
+ def export_to_dest(dest, format)
238
+ mime_type = EXT_TO_CONTENT_TYPE['.' + format] || format
239
+ @session.drive.export_file(id, mime_type, download_dest: dest)
240
+ nil
299
241
  end
300
-
242
+ end
301
243
  end