google_drive 0.3.11 → 1.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.
- 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
|