google_drive 0.3.11 → 1.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -7
- data/README.rdoc +27 -10
- data/lib/google_drive/acl.rb +40 -58
- data/lib/google_drive/acl_entry.rb +76 -56
- data/lib/google_drive/api_client_fetcher.rb +49 -0
- data/lib/google_drive/collection.rb +69 -71
- data/lib/google_drive/file.rb +171 -128
- data/lib/google_drive/session.rb +234 -268
- data/lib/google_drive/spreadsheet.rb +19 -163
- data/lib/google_drive/util.rb +126 -17
- data/lib/google_drive/worksheet.rb +108 -80
- data/lib/google_drive.rb +63 -57
- data/lib/google_drive_v1/acl.rb +115 -0
- data/lib/google_drive_v1/acl_entry.rb +100 -0
- data/lib/google_drive_v1/api_client_fetcher.rb +47 -0
- data/lib/google_drive_v1/authentication_error.rb +14 -0
- data/lib/{google_drive → google_drive_v1}/basic_fetcher.rb +1 -1
- data/lib/{google_drive → google_drive_v1}/client_login_fetcher.rb +2 -2
- data/lib/google_drive_v1/collection.rb +167 -0
- data/lib/google_drive_v1/error.rb +12 -0
- data/lib/google_drive_v1/file.rb +258 -0
- data/lib/google_drive_v1/list.rb +119 -0
- data/lib/google_drive_v1/list_row.rb +88 -0
- data/lib/{google_drive → google_drive_v1}/oauth1_fetcher.rb +1 -1
- data/lib/{google_drive → google_drive_v1}/oauth2_fetcher.rb +2 -2
- data/lib/google_drive_v1/record.rb +31 -0
- data/lib/google_drive_v1/session.rb +522 -0
- data/lib/google_drive_v1/spreadsheet.rb +248 -0
- data/lib/google_drive_v1/table.rb +60 -0
- data/lib/google_drive_v1/util.rb +73 -0
- data/lib/google_drive_v1/worksheet.rb +498 -0
- data/lib/google_drive_v1.rb +148 -0
- metadata +112 -77
- data/doc_src/google_drive/acl_entry.rb +0 -33
@@ -1,7 +1,9 @@
|
|
1
1
|
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
2
|
# The license of this source is "New BSD Licence"
|
3
3
|
|
4
|
+
require "cgi"
|
4
5
|
require "set"
|
6
|
+
require "uri"
|
5
7
|
|
6
8
|
require "google_drive/util"
|
7
9
|
require "google_drive/error"
|
@@ -17,13 +19,11 @@ module GoogleDrive
|
|
17
19
|
|
18
20
|
include(Util)
|
19
21
|
|
20
|
-
def initialize(session, spreadsheet,
|
22
|
+
def initialize(session, spreadsheet, worksheet_feed_entry) #:nodoc:
|
21
23
|
|
22
24
|
@session = session
|
23
25
|
@spreadsheet = spreadsheet
|
24
|
-
|
25
|
-
@title = title
|
26
|
-
@updated = updated
|
26
|
+
set_worksheet_feed_entry(worksheet_feed_entry)
|
27
27
|
|
28
28
|
@cells = nil
|
29
29
|
@input_values = nil
|
@@ -33,31 +33,63 @@ module GoogleDrive
|
|
33
33
|
|
34
34
|
end
|
35
35
|
|
36
|
+
# Nokogiri::XML::Element object of the <entry> element in a worksheets feed.
|
37
|
+
attr_reader(:worksheet_feed_entry)
|
38
|
+
|
39
|
+
# Title of the worksheet (shown as tab label in Web interface).
|
40
|
+
attr_reader(:title)
|
41
|
+
|
42
|
+
# Time object which represents the time the worksheet was last updated.
|
43
|
+
attr_reader(:updated)
|
44
|
+
|
36
45
|
# URL of cell-based feed of the worksheet.
|
37
|
-
|
46
|
+
def cells_feed_url
|
47
|
+
return @worksheet_feed_entry.css(
|
48
|
+
"link[rel='http://schemas.google.com/spreadsheets/2006#cellsfeed']")[0]["href"]
|
49
|
+
end
|
38
50
|
|
39
51
|
# URL of worksheet feed URL of the worksheet.
|
40
52
|
def worksheet_feed_url
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
"
|
48
|
-
|
49
|
-
|
53
|
+
return @worksheet_feed_entry.css("link[rel='self']")[0]["href"]
|
54
|
+
end
|
55
|
+
|
56
|
+
# URL to export the worksheet as CSV.
|
57
|
+
def csv_export_url
|
58
|
+
return @worksheet_feed_entry.css(
|
59
|
+
"link[rel='http://schemas.google.com/spreadsheets/2006#exportcsv']")[0]["href"]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Exports the worksheet as String in CSV format.
|
63
|
+
def export_as_string()
|
64
|
+
api_result = @session.execute!(:uri => self.csv_export_url)
|
65
|
+
return api_result.body
|
66
|
+
end
|
67
|
+
|
68
|
+
# Exports the worksheet to +path+ in CSV format.
|
69
|
+
def export_as_file(path)
|
70
|
+
data = export_as_string()
|
71
|
+
open(path, "w:utf-8"){ |f| f.write(data) }
|
72
|
+
end
|
73
|
+
|
74
|
+
# gid of the worksheet.
|
75
|
+
def gid
|
76
|
+
# A bit tricky but couldn't find a better way.
|
77
|
+
return CGI.parse(URI.parse(self.csv_export_url).query)["gid"].last
|
78
|
+
end
|
79
|
+
|
80
|
+
# URL to view/edit the worksheet in a Web browser.
|
81
|
+
def human_url
|
82
|
+
return "%s\#gid=%s" % [self.spreadsheet.human_url, self.gid]
|
50
83
|
end
|
51
84
|
|
52
85
|
# GoogleDrive::Spreadsheet which this worksheet belongs to.
|
53
86
|
def spreadsheet
|
54
87
|
if !@spreadsheet
|
55
|
-
if !(
|
56
|
-
%r{^https?://spreadsheets.google.com/feeds/cells/(.*)/(.*)/private/full(\?.*)?$})
|
88
|
+
if !(self.worksheet_feed_url =~ %r{https?://spreadsheets\.google\.com/feeds/worksheets/(.*)/(.*)$})
|
57
89
|
raise(GoogleDrive::Error,
|
58
|
-
|
90
|
+
"Worksheet feed URL is in unknown format: #{self.worksheet_feed_url}")
|
59
91
|
end
|
60
|
-
@spreadsheet = @session.
|
92
|
+
@spreadsheet = @session.file_by_id($1)
|
61
93
|
end
|
62
94
|
return @spreadsheet
|
63
95
|
end
|
@@ -85,7 +117,7 @@ module GoogleDrive
|
|
85
117
|
def []=(*args)
|
86
118
|
(row, col) = parse_cell_args(args[0...-1])
|
87
119
|
value = args[-1].to_s()
|
88
|
-
|
120
|
+
reload_cells() if !@cells
|
89
121
|
@cells[[row, col]] = value
|
90
122
|
@input_values[[row, col]] = value
|
91
123
|
@numeric_values[[row, col]] = nil
|
@@ -122,7 +154,7 @@ module GoogleDrive
|
|
122
154
|
# worksheet.input_value(1, 3) #=> "=RC[-2]+RC[-1]"
|
123
155
|
def input_value(*args)
|
124
156
|
(row, col) = parse_cell_args(args)
|
125
|
-
|
157
|
+
reload_cells() if !@cells
|
126
158
|
return @input_values[[row, col]] || ""
|
127
159
|
end
|
128
160
|
|
@@ -141,13 +173,13 @@ module GoogleDrive
|
|
141
173
|
# https://developers.google.com/google-apps/spreadsheets/#working_with_cell-based_feeds
|
142
174
|
def numeric_value(*args)
|
143
175
|
(row, col) = parse_cell_args(args)
|
144
|
-
|
176
|
+
reload_cells() if !@cells
|
145
177
|
return @numeric_values[[row, col]]
|
146
178
|
end
|
147
179
|
|
148
180
|
# Row number of the bottom-most non-empty row.
|
149
181
|
def num_rows
|
150
|
-
|
182
|
+
reload_cells() if !@cells
|
151
183
|
# Memoizes it because this can be bottle-neck.
|
152
184
|
# https://github.com/gimite/google-drive-ruby/pull/49
|
153
185
|
return @num_rows ||= @input_values.select(){ |(r, c), v| !v.empty? }.map(){ |(r, c), v| r }.max || 0
|
@@ -155,7 +187,7 @@ module GoogleDrive
|
|
155
187
|
|
156
188
|
# Column number of the right-most non-empty column.
|
157
189
|
def num_cols
|
158
|
-
|
190
|
+
reload_cells() if !@cells
|
159
191
|
# Memoizes it because this can be bottle-neck.
|
160
192
|
# https://github.com/gimite/google-drive-ruby/pull/49
|
161
193
|
return @num_cols ||= @input_values.select(){ |(r, c), v| !v.empty? }.map(){ |(r, c), v| c }.max || 0
|
@@ -163,54 +195,41 @@ module GoogleDrive
|
|
163
195
|
|
164
196
|
# Number of rows including empty rows.
|
165
197
|
def max_rows
|
166
|
-
|
198
|
+
reload_cells() if !@cells
|
167
199
|
return @max_rows
|
168
200
|
end
|
169
201
|
|
170
202
|
# Updates number of rows.
|
171
203
|
# Note that update is not sent to the server until you call save().
|
172
204
|
def max_rows=(rows)
|
173
|
-
|
205
|
+
reload_cells() if !@cells
|
174
206
|
@max_rows = rows
|
175
207
|
@meta_modified = true
|
176
208
|
end
|
177
209
|
|
178
210
|
# Number of columns including empty columns.
|
179
211
|
def max_cols
|
180
|
-
|
212
|
+
reload_cells() if !@cells
|
181
213
|
return @max_cols
|
182
214
|
end
|
183
215
|
|
184
216
|
# Updates number of columns.
|
185
217
|
# Note that update is not sent to the server until you call save().
|
186
218
|
def max_cols=(cols)
|
187
|
-
|
219
|
+
reload_cells() if !@cells
|
188
220
|
@max_cols = cols
|
189
221
|
@meta_modified = true
|
190
222
|
end
|
191
223
|
|
192
|
-
# Title of the worksheet (shown as tab label in Web interface).
|
193
|
-
def title
|
194
|
-
reload() if !@title
|
195
|
-
return @title
|
196
|
-
end
|
197
|
-
|
198
|
-
# Date updated of the worksheet (shown as tab label in Web interface).
|
199
|
-
def updated
|
200
|
-
reload() if !@updated
|
201
|
-
return @updated
|
202
|
-
end
|
203
|
-
|
204
224
|
# Updates title of the worksheet.
|
205
225
|
# Note that update is not sent to the server until you call save().
|
206
226
|
def title=(title)
|
207
|
-
reload() if !@cells
|
208
227
|
@title = title
|
209
228
|
@meta_modified = true
|
210
229
|
end
|
211
230
|
|
212
231
|
def cells #:nodoc:
|
213
|
-
|
232
|
+
reload_cells() if !@cells
|
214
233
|
return @cells
|
215
234
|
end
|
216
235
|
|
@@ -229,31 +248,9 @@ module GoogleDrive
|
|
229
248
|
# Reloads content of the worksheets from the server.
|
230
249
|
# Note that changes you made by []= etc. is discarded if you haven't called save().
|
231
250
|
def reload()
|
232
|
-
|
233
|
-
|
234
|
-
@max_rows = doc.css("gs|rowCount").text.to_i()
|
235
|
-
@max_cols = doc.css("gs|colCount").text.to_i()
|
236
|
-
@title = doc.css("feed > title")[0].text
|
237
|
-
|
238
|
-
@num_cols = nil
|
239
|
-
@num_rows = nil
|
240
|
-
|
241
|
-
@cells = {}
|
242
|
-
@input_values = {}
|
243
|
-
@numeric_values = {}
|
244
|
-
doc.css("feed > entry").each() do |entry|
|
245
|
-
cell = entry.css("gs|cell")[0]
|
246
|
-
row = cell["row"].to_i()
|
247
|
-
col = cell["col"].to_i()
|
248
|
-
@cells[[row, col]] = cell.inner_text
|
249
|
-
@input_values[[row, col]] = cell["inputValue"] || cell.inner_text
|
250
|
-
numeric_value = cell["numericValue"]
|
251
|
-
@numeric_values[[row, col]] = numeric_value ? numeric_value.to_f() : nil
|
252
|
-
end
|
253
|
-
@modified.clear()
|
254
|
-
@meta_modified = false
|
251
|
+
set_worksheet_feed_entry(@session.request(:get, self.worksheet_feed_url).root)
|
252
|
+
reload_cells()
|
255
253
|
return true
|
256
|
-
|
257
254
|
end
|
258
255
|
|
259
256
|
# Saves your changes made by []=, etc. to the server.
|
@@ -263,8 +260,7 @@ module GoogleDrive
|
|
263
260
|
|
264
261
|
if @meta_modified
|
265
262
|
|
266
|
-
|
267
|
-
edit_url = ws_doc.css("link[rel='edit']")[0]["href"]
|
263
|
+
edit_url = @worksheet_feed_entry.css("link[rel='edit']")[0]["href"]
|
268
264
|
xml = <<-"EOS"
|
269
265
|
<entry xmlns='http://www.w3.org/2005/Atom'
|
270
266
|
xmlns:gs='http://schemas.google.com/spreadsheets/2006'>
|
@@ -274,11 +270,11 @@ module GoogleDrive
|
|
274
270
|
</entry>
|
275
271
|
EOS
|
276
272
|
|
277
|
-
@session.request(
|
273
|
+
result = @session.request(
|
278
274
|
:put, edit_url, :data => xml,
|
279
275
|
:header => {"Content-Type" => "application/atom+xml;charset=utf-8", "If-Match" => "*"})
|
276
|
+
set_worksheet_feed_entry(result.root)
|
280
277
|
|
281
|
-
@meta_modified = false
|
282
278
|
sent = true
|
283
279
|
|
284
280
|
end
|
@@ -290,7 +286,7 @@ module GoogleDrive
|
|
290
286
|
cell_entries = {}
|
291
287
|
rows = @modified.map(){ |r, c| r }
|
292
288
|
cols = @modified.map(){ |r, c| c }
|
293
|
-
url = concat_url(
|
289
|
+
url = concat_url(self.cells_feed_url,
|
294
290
|
"?return-empty=true&min-row=#{rows.min}&max-row=#{rows.max}" +
|
295
291
|
"&min-col=#{cols.min}&max-col=#{cols.max}")
|
296
292
|
doc = @session.request(:get, url)
|
@@ -309,7 +305,7 @@ module GoogleDrive
|
|
309
305
|
<feed xmlns="http://www.w3.org/2005/Atom"
|
310
306
|
xmlns:batch="http://schemas.google.com/gdata/batch"
|
311
307
|
xmlns:gs="http://schemas.google.com/spreadsheets/2006">
|
312
|
-
<id>#{h(
|
308
|
+
<id>#{h(self.cells_feed_url)}</id>
|
313
309
|
EOS
|
314
310
|
for row, col in chunk
|
315
311
|
value = @cells[[row, col]]
|
@@ -331,9 +327,13 @@ module GoogleDrive
|
|
331
327
|
</feed>
|
332
328
|
EOS
|
333
329
|
|
334
|
-
batch_url = concat_url(
|
335
|
-
result = @session.request(
|
336
|
-
|
330
|
+
batch_url = concat_url(self.cells_feed_url, "/batch")
|
331
|
+
result = @session.request(
|
332
|
+
:post,
|
333
|
+
batch_url,
|
334
|
+
:data => xml,
|
335
|
+
:header => {"Content-Type" => "application/atom+xml;charset=utf-8", "If-Match" => "*"})
|
336
|
+
for entry in result.css("entry")
|
337
337
|
interrupted = entry.css("batch|interrupted")[0]
|
338
338
|
if interrupted
|
339
339
|
raise(GoogleDrive::Error, "Update has failed: %s" %
|
@@ -341,7 +341,7 @@ module GoogleDrive
|
|
341
341
|
end
|
342
342
|
if !(entry.css("batch|status").first["code"] =~ /^2/)
|
343
343
|
raise(GoogleDrive::Error, "Updating cell %s has failed: %s" %
|
344
|
-
[entry.css("
|
344
|
+
[entry.css("id").text, entry.css("batch|status")[0]["reason"]])
|
345
345
|
end
|
346
346
|
end
|
347
347
|
|
@@ -424,11 +424,7 @@ module GoogleDrive
|
|
424
424
|
|
425
425
|
# List feed URL of the worksheet.
|
426
426
|
def list_feed_url
|
427
|
-
|
428
|
-
entry = @session.request(:get, self.worksheet_feed_url)
|
429
|
-
|
430
|
-
# Gets the URL of list-based feed for the given spreadsheet.
|
431
|
-
return entry.css(
|
427
|
+
return @worksheet_feed_entry.css(
|
432
428
|
"link[rel='http://schemas.google.com/spreadsheets/2006#listfeed']")[0]["href"]
|
433
429
|
end
|
434
430
|
|
@@ -477,6 +473,38 @@ module GoogleDrive
|
|
477
473
|
|
478
474
|
private
|
479
475
|
|
476
|
+
def set_worksheet_feed_entry(entry)
|
477
|
+
@worksheet_feed_entry = entry
|
478
|
+
@title = entry.css("title").text
|
479
|
+
@updated = Time.parse(entry.css("updated").text)
|
480
|
+
@meta_modified = false
|
481
|
+
end
|
482
|
+
|
483
|
+
def reload_cells()
|
484
|
+
|
485
|
+
doc = @session.request(:get, self.cells_feed_url)
|
486
|
+
@max_rows = doc.css("gs|rowCount").text.to_i()
|
487
|
+
@max_cols = doc.css("gs|colCount").text.to_i()
|
488
|
+
|
489
|
+
@num_cols = nil
|
490
|
+
@num_rows = nil
|
491
|
+
|
492
|
+
@cells = {}
|
493
|
+
@input_values = {}
|
494
|
+
@numeric_values = {}
|
495
|
+
doc.css("feed > entry").each() do |entry|
|
496
|
+
cell = entry.css("gs|cell")[0]
|
497
|
+
row = cell["row"].to_i()
|
498
|
+
col = cell["col"].to_i()
|
499
|
+
@cells[[row, col]] = cell.inner_text
|
500
|
+
@input_values[[row, col]] = cell["inputValue"] || cell.inner_text
|
501
|
+
numeric_value = cell["numericValue"]
|
502
|
+
@numeric_values[[row, col]] = numeric_value ? numeric_value.to_f() : nil
|
503
|
+
end
|
504
|
+
@modified.clear()
|
505
|
+
|
506
|
+
end
|
507
|
+
|
480
508
|
def parse_cell_args(args)
|
481
509
|
if args.size == 1 && args[0].is_a?(String)
|
482
510
|
return cell_name_to_row_col(args[0])
|
data/lib/google_drive.rb
CHANGED
@@ -1,76 +1,84 @@
|
|
1
1
|
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
2
|
# The license of this source is "New BSD Licence"
|
3
3
|
|
4
|
-
require "rubygems"
|
5
|
-
require "google/api_client"
|
6
4
|
require "json"
|
5
|
+
require "google/api_client"
|
7
6
|
|
8
7
|
require "google_drive/session"
|
9
8
|
|
10
9
|
|
11
10
|
module GoogleDrive
|
12
11
|
|
13
|
-
# Authenticates with given +mail+ and +password+, and returns GoogleDrive::Session
|
14
|
-
# if succeeds. Raises GoogleDrive::AuthenticationError if fails.
|
15
|
-
# Google Apps account is supported.
|
16
|
-
#
|
17
|
-
# +proxy+ is deprecated, and will be removed in the next version.
|
18
|
-
def self.login(mail, password, proxy = nil)
|
19
|
-
return Session.login(mail, password, proxy)
|
20
|
-
end
|
21
|
-
|
22
12
|
# Authenticates with given OAuth2 token.
|
23
13
|
#
|
24
|
-
# +access_token+ can be either OAuth2 access_token string or OAuth2::AccessToken.
|
25
|
-
# Specifying OAuth::AccessToken is deprecated, and will not work in the next version.
|
26
|
-
#
|
27
|
-
# +proxy+ is deprecated, and will be removed in the next version.
|
14
|
+
# +access_token+ can be either OAuth2 access_token string, or OAuth2::AccessToken.
|
28
15
|
#
|
29
|
-
# OAuth2 code example:
|
16
|
+
# OAuth2 code example for Web apps:
|
30
17
|
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
18
|
+
# require "rubygems"
|
19
|
+
# require "google/api_client"
|
20
|
+
# client = Google::APIClient.new
|
21
|
+
# auth = client.authorization
|
22
|
+
# # Follow "Create a client ID and client secret" in
|
23
|
+
# # https://developers.google.com/drive/web/auth/web-server] to get a client ID and client secret.
|
24
|
+
# auth.client_id = "YOUR CLIENT ID"
|
25
|
+
# auth.client_secret = "YOUR CLIENT SECRET"
|
26
|
+
# auth.scope =
|
27
|
+
# "https://www.googleapis.com/auth/drive " +
|
28
|
+
# "https://spreadsheets.google.com/feeds/"
|
29
|
+
# auth.redirect_uri = "http://example.com/redirect"
|
30
|
+
# auth_url = auth.authorization_uri
|
42
31
|
# # Redirect the user to auth_url and get authorization code from redirect URL.
|
43
|
-
#
|
44
|
-
#
|
45
|
-
# session = GoogleDrive.login_with_oauth(
|
32
|
+
# auth.code = authorization_code
|
33
|
+
# auth.fetch_access_token!
|
34
|
+
# session = GoogleDrive.login_with_oauth(auth.access_token)
|
46
35
|
#
|
47
|
-
#
|
36
|
+
# auth.access_token expires in 1 hour. If you want to restore a session afterwards, you can store
|
37
|
+
# auth.refresh_token somewhere after auth.fetch_access_token! above, and use this code:
|
48
38
|
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
39
|
+
# require "rubygems"
|
40
|
+
# require "google/api_client"
|
41
|
+
# client = Google::APIClient.new
|
42
|
+
# auth = client.authorization
|
43
|
+
# # Follow "Create a client ID and client secret" in
|
44
|
+
# # https://developers.google.com/drive/web/auth/web-server] to get a client ID and client secret.
|
45
|
+
# auth.client_id = "YOUR CLIENT ID"
|
46
|
+
# auth.client_secret = "YOUR CLIENT SECRET"
|
47
|
+
# auth.scope =
|
48
|
+
# "https://www.googleapis.com/auth/drive " +
|
49
|
+
# "https://spreadsheets.google.com/feeds/"
|
50
|
+
# auth.redirect_uri = "http://example.com/redirect"
|
51
|
+
# auth.refresh_token = refresh_token
|
52
|
+
# auth.fetch_access_token!
|
53
|
+
# session = GoogleDrive.login_with_oauth(auth.access_token)
|
53
54
|
#
|
54
|
-
#
|
55
|
-
# authorization code is shown after authorization.
|
55
|
+
# OAuth2 code example for command-line apps:
|
56
56
|
#
|
57
|
-
#
|
57
|
+
# require "rubygems"
|
58
|
+
# require "google/api_client"
|
59
|
+
# client = Google::APIClient.new
|
60
|
+
# auth = client.authorization
|
61
|
+
# # Follow "Create a client ID and client secret" in
|
62
|
+
# # https://developers.google.com/drive/web/auth/web-server] to get a client ID and client secret.
|
63
|
+
# auth.client_id = "YOUR CLIENT ID"
|
64
|
+
# auth.client_secret = "YOUR CLIENT SECRET"
|
65
|
+
# auth.scope =
|
66
|
+
# "https://www.googleapis.com/auth/drive " +
|
67
|
+
# "https://spreadsheets.google.com/feeds/"
|
68
|
+
# auth.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
|
69
|
+
# print("1. Open this page:\n%s\n\n" % auth.authorization_uri)
|
70
|
+
# print("2. Enter the authorization code shown in the page: ")
|
71
|
+
# auth.code = $stdin.gets.chomp
|
72
|
+
# auth.fetch_access_token!
|
73
|
+
# session = GoogleDrive.login_with_oauth(auth.access_token)
|
58
74
|
#
|
59
|
-
#
|
60
|
-
# - http://code.google.com/apis/accounts/docs/OAuth2.html
|
61
|
-
# - http://oauth.rubyforge.org/
|
62
|
-
# - http://code.google.com/apis/accounts/docs/OAuth.html
|
63
|
-
def self.login_with_oauth(access_token, proxy = nil)
|
64
|
-
return Session.login_with_oauth(access_token, proxy)
|
65
|
-
end
|
66
|
-
|
67
|
-
# Restores session using return value of auth_tokens method of previous session.
|
75
|
+
# See this document for details:
|
68
76
|
#
|
69
|
-
#
|
70
|
-
def self.
|
71
|
-
return Session.
|
77
|
+
# - https://developers.google.com/drive/web/about-auth
|
78
|
+
def self.login_with_oauth(client_or_access_token, proxy = nil)
|
79
|
+
return Session.new(client_or_access_token, proxy)
|
72
80
|
end
|
73
|
-
|
81
|
+
|
74
82
|
# Restores GoogleDrive::Session from +path+ and returns it.
|
75
83
|
# If +path+ doesn't exist or authentication has failed, prompts the user to authorize the access,
|
76
84
|
# stores the session to +path+ and returns it.
|
@@ -111,16 +119,14 @@ module GoogleDrive
|
|
111
119
|
|
112
120
|
client = Google::APIClient.new(
|
113
121
|
:application_name => "google_drive Ruby library",
|
114
|
-
:application_version => "0.
|
122
|
+
:application_version => "0.4.0"
|
115
123
|
)
|
116
124
|
auth = client.authorization
|
117
125
|
auth.client_id = client_id
|
118
126
|
auth.client_secret = client_secret
|
119
127
|
auth.scope =
|
120
128
|
"https://www.googleapis.com/auth/drive " +
|
121
|
-
"https://spreadsheets.google.com/feeds/
|
122
|
-
"https://docs.google.com/feeds/ " +
|
123
|
-
"https://docs.googleusercontent.com/"
|
129
|
+
"https://spreadsheets.google.com/feeds/"
|
124
130
|
auth.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
|
125
131
|
|
126
132
|
if token_data
|
@@ -141,8 +147,8 @@ module GoogleDrive
|
|
141
147
|
|
142
148
|
end
|
143
149
|
|
144
|
-
return GoogleDrive.login_with_oauth(
|
150
|
+
return GoogleDrive.login_with_oauth(client)
|
145
151
|
|
146
152
|
end
|
147
|
-
|
153
|
+
|
148
154
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# Author: Guy Boertje <https://github.com/guyboertje>
|
2
|
+
# Author: David R. Albrecht <https://github.com/eldavido>
|
3
|
+
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
4
|
+
# The license of this source is "New BSD Licence"
|
5
|
+
|
6
|
+
require "google_drive_v1/acl_entry"
|
7
|
+
|
8
|
+
module GoogleDriveV1
|
9
|
+
|
10
|
+
# ACL (access control list) of a spreadsheet.
|
11
|
+
#
|
12
|
+
# Use GoogleDriveV1::Spreadsheet#acl to get GoogleDriveV1::Acl object.
|
13
|
+
# See GoogleDriveV1::Spreadsheet#acl for usage example.
|
14
|
+
#
|
15
|
+
# This code is based on https://github.com/guyboertje/gdata-spreadsheet-ruby .
|
16
|
+
class Acl
|
17
|
+
|
18
|
+
include(Util)
|
19
|
+
extend(Forwardable)
|
20
|
+
|
21
|
+
def initialize(session, acls_feed_url) #:nodoc:
|
22
|
+
@session = session
|
23
|
+
@acls_feed_url = acls_feed_url
|
24
|
+
header = {"GData-Version" => "3.0"}
|
25
|
+
doc = @session.request(:get, @acls_feed_url, :header => header, :auth => :writely)
|
26
|
+
@acls = doc.css("entry").map(){ |e| AclEntry.new(entry_to_params(e)) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def_delegators(:@acls, :size, :[], :each)
|
30
|
+
|
31
|
+
# Adds a new entry. +entry+ is either a GoogleDriveV1::AclEntry or a Hash with keys
|
32
|
+
# :scope_type, :scope and :role. See GoogleDriveV1::AclEntry#scope_type and
|
33
|
+
# GoogleDriveV1::AclEntry#role for the document of the fields.
|
34
|
+
#
|
35
|
+
# NOTE: This sends email to the new people.
|
36
|
+
#
|
37
|
+
# e.g.
|
38
|
+
# # A specific user can read or write.
|
39
|
+
# spreadsheet.acl.push(
|
40
|
+
# {:scope_type => "user", :scope => "example2@gmail.com", :role => "reader"})
|
41
|
+
# spreadsheet.acl.push(
|
42
|
+
# {:scope_type => "user", :scope => "example3@gmail.com", :role => "writer"})
|
43
|
+
# # Publish on the Web.
|
44
|
+
# spreadsheet.acl.push(
|
45
|
+
# {:scope_type => "default", :role => "reader"})
|
46
|
+
# # Anyone who knows the link can read.
|
47
|
+
# spreadsheet.acl.push(
|
48
|
+
# {:scope_type => "default", :with_key => true, :role => "reader"})
|
49
|
+
def push(entry)
|
50
|
+
|
51
|
+
entry = AclEntry.new(entry) if entry.is_a?(Hash)
|
52
|
+
|
53
|
+
header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml;charset=utf-8"}
|
54
|
+
doc = @session.request(
|
55
|
+
:post, @acls_feed_url, :data => entry.to_xml(), :header => header, :auth => :writely)
|
56
|
+
|
57
|
+
entry.params = entry_to_params(doc.root)
|
58
|
+
@acls.push(entry)
|
59
|
+
return entry
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# Deletes an ACL entry.
|
64
|
+
#
|
65
|
+
# e.g.
|
66
|
+
# spreadsheet.acl.delete(spreadsheet.acl[1])
|
67
|
+
def delete(entry)
|
68
|
+
header = {"GData-Version" => "3.0"}
|
69
|
+
@session.request(:delete, entry.edit_url_internal, :header => header, :auth => :writely)
|
70
|
+
@acls.delete(entry)
|
71
|
+
end
|
72
|
+
|
73
|
+
def update_role(entry) #:nodoc:
|
74
|
+
|
75
|
+
header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml;charset=utf-8"}
|
76
|
+
doc = @session.request(
|
77
|
+
:put, entry.edit_url_internal, :data => entry.to_xml(), :header => header, :auth => :writely)
|
78
|
+
|
79
|
+
entry.params = entry_to_params(doc.root)
|
80
|
+
return entry
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
def inspect
|
85
|
+
return "\#<%p %p>" % [self.class, @acls]
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def entry_to_params(entry)
|
91
|
+
|
92
|
+
if !entry.css("gAcl|withKey").empty?
|
93
|
+
with_key = true
|
94
|
+
role = entry.css("gAcl|withKey gAcl|role")[0]["value"]
|
95
|
+
else
|
96
|
+
with_key = false
|
97
|
+
role = entry.css("gAcl|role")[0]["value"]
|
98
|
+
end
|
99
|
+
|
100
|
+
return {
|
101
|
+
:acl => self,
|
102
|
+
:scope_type => entry.css("gAcl|scope")[0]["type"],
|
103
|
+
:scope => entry.css("gAcl|scope")[0]["value"],
|
104
|
+
:with_key => with_key,
|
105
|
+
:role => role,
|
106
|
+
:title => entry.css("title").text,
|
107
|
+
:edit_url => entry.css("link[rel='edit']")[0]["href"],
|
108
|
+
:etag => entry["etag"],
|
109
|
+
}
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|