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.
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