google_drive 1.0.6 → 2.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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