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.
Files changed (34) hide show
  1. checksums.yaml +7 -7
  2. data/README.rdoc +27 -10
  3. data/lib/google_drive/acl.rb +40 -58
  4. data/lib/google_drive/acl_entry.rb +76 -56
  5. data/lib/google_drive/api_client_fetcher.rb +49 -0
  6. data/lib/google_drive/collection.rb +69 -71
  7. data/lib/google_drive/file.rb +171 -128
  8. data/lib/google_drive/session.rb +234 -268
  9. data/lib/google_drive/spreadsheet.rb +19 -163
  10. data/lib/google_drive/util.rb +126 -17
  11. data/lib/google_drive/worksheet.rb +108 -80
  12. data/lib/google_drive.rb +63 -57
  13. data/lib/google_drive_v1/acl.rb +115 -0
  14. data/lib/google_drive_v1/acl_entry.rb +100 -0
  15. data/lib/google_drive_v1/api_client_fetcher.rb +47 -0
  16. data/lib/google_drive_v1/authentication_error.rb +14 -0
  17. data/lib/{google_drive → google_drive_v1}/basic_fetcher.rb +1 -1
  18. data/lib/{google_drive → google_drive_v1}/client_login_fetcher.rb +2 -2
  19. data/lib/google_drive_v1/collection.rb +167 -0
  20. data/lib/google_drive_v1/error.rb +12 -0
  21. data/lib/google_drive_v1/file.rb +258 -0
  22. data/lib/google_drive_v1/list.rb +119 -0
  23. data/lib/google_drive_v1/list_row.rb +88 -0
  24. data/lib/{google_drive → google_drive_v1}/oauth1_fetcher.rb +1 -1
  25. data/lib/{google_drive → google_drive_v1}/oauth2_fetcher.rb +2 -2
  26. data/lib/google_drive_v1/record.rb +31 -0
  27. data/lib/google_drive_v1/session.rb +522 -0
  28. data/lib/google_drive_v1/spreadsheet.rb +248 -0
  29. data/lib/google_drive_v1/table.rb +60 -0
  30. data/lib/google_drive_v1/util.rb +73 -0
  31. data/lib/google_drive_v1/worksheet.rb +498 -0
  32. data/lib/google_drive_v1.rb +148 -0
  33. metadata +112 -77
  34. 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, cells_feed_url, title = nil, updated = nil) #:nodoc:
22
+ def initialize(session, spreadsheet, worksheet_feed_entry) #:nodoc:
21
23
 
22
24
  @session = session
23
25
  @spreadsheet = spreadsheet
24
- @cells_feed_url = cells_feed_url
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
- attr_reader(:cells_feed_url)
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
- # I don't know good way to get worksheet feed URL from cells feed URL.
42
- # Probably it would be cleaner to keep worksheet feed URL and get cells feed URL
43
- # from it.
44
- if !(@cells_feed_url =~
45
- %r{^https?://spreadsheets.google.com/feeds/cells/(.*)/(.*)/private/full((\?.*)?)$})
46
- raise(GoogleDrive::Error,
47
- "Cells feed URL is in unknown format: #{@cells_feed_url}")
48
- end
49
- return "https://spreadsheets.google.com/feeds/worksheets/#{$1}/private/full/#{$2}#{$3}"
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 !(@cells_feed_url =~
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
- "Cells feed URL is in unknown format: #{@cells_feed_url}")
90
+ "Worksheet feed URL is in unknown format: #{self.worksheet_feed_url}")
59
91
  end
60
- @spreadsheet = @session.spreadsheet_by_key($1)
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
- reload() if !@cells
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
- reload() if !@cells
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
- reload() if !@cells
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
- reload() if !@cells
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
- reload() if !@cells
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
- reload() if !@cells
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
- reload() if !@cells
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
- reload() if !@cells
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
- reload() if !@cells
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
- reload() if !@cells
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
- doc = @session.request(:get, @cells_feed_url)
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
- ws_doc = @session.request(:get, self.worksheet_feed_url)
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(@cells_feed_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(@cells_feed_url)}</id>
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(@cells_feed_url, "/batch")
335
- result = @session.request(:post, batch_url, :data => xml, :header => {"Content-Type" => "application/atom+xml;charset=utf-8", "If-Match" => "*"})
336
- for entry in result.css("atom|entry")
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("atom|id").text, entry.css("batch|status")[0]["reason"]])
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
- # Gets the worksheets metafeed.
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
- # client = OAuth2::Client.new(
32
- # your_client_id, your_client_secret,
33
- # :site => "https://accounts.google.com",
34
- # :token_url => "/o/oauth2/token",
35
- # :authorize_url => "/o/oauth2/auth")
36
- # auth_url = client.auth_code.authorize_url(
37
- # :redirect_uri => "http://example.com/",
38
- # :scope =>
39
- # "https://docs.google.com/feeds/ " +
40
- # "https://docs.googleusercontent.com/ " +
41
- # "https://spreadsheets.google.com/feeds/")
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
- # auth_token = client.auth_code.get_token(
44
- # authorization_code, :redirect_uri => "http://example.com/")
45
- # session = GoogleDrive.login_with_oauth(auth_token.token)
32
+ # auth.code = authorization_code
33
+ # auth.fetch_access_token!
34
+ # session = GoogleDrive.login_with_oauth(auth.access_token)
46
35
  #
47
- # Or, from existing refresh token:
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
- # auth_token = OAuth2::AccessToken.from_hash(client,
50
- # {:refresh_token => refresh_token, :expires_at => expires_at})
51
- # auth_token = auth_token.refresh!
52
- # session = GoogleDrive.login_with_oauth(auth_token.token)
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
- # If your app is not a Web app, use "urn:ietf:wg:oauth:2.0:oob" as redirect_url. Then
55
- # authorization code is shown after authorization.
55
+ # OAuth2 code example for command-line apps:
56
56
  #
57
- # See these documents for details:
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
- # - https://github.com/intridea/oauth2
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
- # See GoogleDrive.login for description of parameter +proxy+.
70
- def self.restore_session(auth_tokens, proxy = nil)
71
- return Session.restore_session(auth_tokens, proxy)
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.3.11"
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(auth.access_token)
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