google_drive 0.3.0 → 0.3.1

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.
data/README.rdoc CHANGED
@@ -1,5 +1,7 @@
1
1
  This is a Ruby 1.8/1.9 library to read/write files/spreadsheets in Google Drive/Docs.
2
2
 
3
+ NOTE: This is NOT a library to create Google Drive App.
4
+
3
5
 
4
6
  = How to install
5
7
 
data/lib/google_drive.rb CHANGED
@@ -29,7 +29,10 @@ module GoogleDrive
29
29
  # :authorize_url => "/o/oauth2/auth")
30
30
  # auth_url = client.auth_code.authorize_url(
31
31
  # :redirect_uri => "http://example.com/",
32
- # "scope" => "https://spreadsheets.google.com/feeds https://docs.google.com/feeds/")
32
+ # :scope =>
33
+ # "https://docs.google.com/feeds/ " +
34
+ # "https://docs.googleusercontent.com/ " +
35
+ # "https://spreadsheets.google.com/feeds/")
33
36
  # # Redirect the user to auth_url and get authorization code from redirect URL.
34
37
  # auth_token = client.auth_code.get_token(
35
38
  # authorization_code, :redirect_uri => "http://example.com/")
@@ -42,6 +45,9 @@ module GoogleDrive
42
45
  # access_token = access_token.refresh!
43
46
  # session = GoogleDrive.login_with_oauth(access_token)
44
47
  #
48
+ # If your app is not a Web app, use "urn:ietf:wg:oauth:2.0:oob" as redirect_url. Then
49
+ # authorization code is shown after authorization.
50
+ #
45
51
  # OAuth1 code example:
46
52
  #
47
53
  # 1) First generate OAuth consumer object with key and secret for your site by registering site
@@ -8,21 +8,45 @@ require "google_drive/spreadsheet"
8
8
 
9
9
  module GoogleDrive
10
10
 
11
- # Use GoogleDrive::Session#collection_by_url to get GoogleDrive::Collection object.
12
- class Collection
11
+ # Use GoogleDrive::Session#root_collection, GoogleDrive::Collection#subcollections,
12
+ # or GoogleDrive::Session#collection_by_url to get GoogleDrive::Collection object.
13
+ class Collection < GoogleDrive::File
13
14
 
14
15
  include(Util)
15
16
 
16
- def initialize(session, collection_feed_url) #:nodoc:
17
- @session = session
18
- @collection_feed_url = collection_feed_url
17
+ #:nodoc:
18
+ ROOT_URL = "#{DOCS_BASE_URL}/folder%3Aroot"
19
+
20
+ alias collection_feed_url document_feed_url
21
+
22
+ def contents_url
23
+ if self.root?
24
+ # The root collection doesn't have document feed.
25
+ return concat_url(ROOT_URL, "/contents")
26
+ else
27
+ return self.document_feed_entry.css(
28
+ "content[type='application/atom+xml;type=feed']")[0]["src"]
29
+ end
19
30
  end
20
31
 
21
- attr_reader(:collection_feed_url)
32
+ # Title of the collection.
33
+ #
34
+ # Set <tt>params[:reload]</tt> to true to force reloading the title.
35
+ def title(params = {})
36
+ if self.root?
37
+ # The root collection doesn't have document feed.
38
+ return nil
39
+ else
40
+ return super
41
+ end
42
+ end
43
+
44
+ def resource_id
45
+ return self.root? ? nil : super
46
+ end
22
47
 
23
48
  # Adds the given GoogleDrive::File to the collection.
24
49
  def add(file)
25
- contents_url = concat_url(@collection_feed_url, "/contents")
26
50
  header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
27
51
  xml = <<-"EOS"
28
52
  <entry xmlns="http://www.w3.org/2005/Atom">
@@ -30,25 +54,87 @@ module GoogleDrive
30
54
  </entry>
31
55
  EOS
32
56
  @session.request(
33
- :post, contents_url, :data => xml, :header => header, :auth => :writely)
57
+ :post, self.contents_url, :data => xml, :header => header, :auth => :writely)
34
58
  return nil
35
59
  end
36
60
 
37
- # Returns all the files in the collection.
38
- def files
39
- contents_url = concat_url(@collection_feed_url, "/contents")
61
+ # Creates a sub-collection with given title. Returns GoogleDrive::Collection object.
62
+ def create_subcollection(title)
40
63
  header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
41
- doc = @session.request(:get, contents_url, :header => header, :auth => :writely)
42
- return doc.css("feed > entry").map(){ |e| @session.entry_element_to_file(e) }
64
+ xml = <<-EOS
65
+ <entry xmlns="http://www.w3.org/2005/Atom">
66
+ <category scheme="http://schemas.google.com/g/2005#kind"
67
+ term="http://schemas.google.com/docs/2007#folder"/>
68
+ <title>#{h(title)}</title>
69
+ </entry>
70
+ EOS
71
+ doc = @session.request(
72
+ :post, contents_url, :data => xml, :header => header, :auth => :writely)
73
+ return @session.entry_element_to_file(doc)
43
74
  end
44
-
75
+
76
+ # Removes the given GoogleDrive::File from the collection.
77
+ def remove(file)
78
+ url = to_v3_url("#{contents_url}/#{file.resource_id}")
79
+ @session.request(:delete, url, :auth => :writely, :header => {"If-Match" => "*"})
80
+ end
81
+
82
+ # Returns true if this is a root collection
83
+ def root?
84
+ self.document_feed_url == ROOT_URL
85
+ end
86
+
87
+ # Returns all the files (including spreadsheets, documents, subcollections) in the collection.
88
+ #
89
+ # You can specify query parameters described at
90
+ # https://developers.google.com/google-apps/documents-list/#getting_a_list_of_documents_and_files
91
+ #
92
+ # e.g.
93
+ #
94
+ # # Gets all the files in collection, including subcollections.
95
+ # collection.files
96
+ #
97
+ # # Gets only files with title "hoge".
98
+ # collection.files("title" => "hoge", "title-exact" => "true")
99
+ def files(params = {})
100
+ return files_with_type(nil, params)
101
+ end
102
+
103
+ alias contents files
104
+
45
105
  # Returns all the spreadsheets in the collection.
46
- def spreadsheets
47
- return self.files.select(){ |f| f.is_a?(Spreadsheet) }
106
+ def spreadsheets(params = {})
107
+ return files_with_type("spreadsheet", params)
108
+ end
109
+
110
+ # Returns all the Google Docs documents in the collection.
111
+ def documents(params = {})
112
+ return files_with_type("document", params)
113
+ end
114
+
115
+ # Returns all its subcollections.
116
+ def subcollections(params = {})
117
+ return files_with_type("folder", params)
118
+ end
119
+
120
+ # Returns its subcollection whose title exactly matches +title+ as GoogleDrive::Collection.
121
+ # Returns nil if not found. If multiple collections with the +title+ are found, returns
122
+ # one of them.
123
+ def subcollection_by_title(title)
124
+ return subcollections("title" => title, "title-exact" => "true")[0]
48
125
  end
49
126
 
50
- # TODO Add other operations.
127
+ private
51
128
 
129
+ def files_with_type(type, params = {})
130
+ contents_url = self.contents_url
131
+ contents_url = concat_url(contents_url, "/-/#{type}") if type
132
+ contents_url = concat_url(contents_url, "?" + encode_query(params))
133
+ header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
134
+ doc = @session.request(:get, contents_url, :header => header, :auth => :writely)
135
+ return doc.css("feed > entry").map(){ |e| @session.entry_element_to_file(e) }
136
+ end
137
+
52
138
  end
53
139
 
54
140
  end
@@ -1,6 +1,7 @@
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 "stringio"
5
6
 
6
7
  require "google_drive/util"
@@ -17,11 +18,24 @@ module GoogleDrive
17
18
 
18
19
  include(Util)
19
20
 
20
- def initialize(session, entry) #:nodoc:
21
+ def initialize(session, entry_or_url) #:nodoc:
21
22
  @session = session
22
- @document_feed_entry = entry
23
- @document_feed_url = entry ? entry.css("link[rel='self']")[0]["href"] : nil
24
- @title = entry ? entry.css("title")[0].text : nil
23
+ if !entry_or_url
24
+ # TODO Delete this after editing spreadsheet.rb.
25
+ @document_feed_entry = nil
26
+ @document_feed_url = entry_or_url
27
+ elsif entry_or_url.is_a?(String)
28
+ @document_feed_entry = nil
29
+ @document_feed_url = entry_or_url
30
+ else
31
+ @document_feed_entry = entry_or_url
32
+ # This is usually equal to the URL in <link rel="self">. But the URL in
33
+ # <link rel="self"> in collection feed is e.g.
34
+ # https://docs.google.com/feeds/default/private/full/folder%3Aroot/contents/folder%3Axxx
35
+ # and deletion of the URL doesn't delete the file itself.
36
+ # So we construct the URL here using resource ID instead.
37
+ @document_feed_url = "%s/%s" % [DOCS_BASE_URL, CGI.escape(self.resource_id)]
38
+ end
25
39
  @acl = nil
26
40
  end
27
41
 
@@ -29,10 +43,32 @@ module GoogleDrive
29
43
  attr_reader(:document_feed_url)
30
44
 
31
45
  # <entry> element of document list feed as Nokogiri::XML::Element.
32
- attr_reader(:document_feed_entry)
33
-
46
+ #
47
+ # Set <tt>params[:reload]</tt> to true to force reloading the feed.
48
+ def document_feed_entry(params = {})
49
+ if !@document_feed_entry || params[:reload]
50
+ @document_feed_entry =
51
+ @session.request(:get, self.document_feed_url, :auth => :writely).css("entry")[0]
52
+ end
53
+ return @document_feed_entry
54
+ end
55
+
56
+ # Resource ID.
57
+ def resource_id
58
+ return self.document_feed_entry.css("gd|resourceId").text
59
+ end
60
+
61
+ # The type of resourse. e.g. "document", "spreadsheet", "folder"
62
+ def resource_type
63
+ return self.resource_id.split(/:/)[0]
64
+ end
65
+
34
66
  # Title of the file.
35
- attr_reader(:title)
67
+ #
68
+ # Set <tt>params[:reload]</tt> to true to force reloading the title.
69
+ def title(params = {})
70
+ return document_feed_entry(params).css("title").text
71
+ end
36
72
 
37
73
  # URL to view/edit the file in a Web browser.
38
74
  #
@@ -50,7 +86,7 @@ module GoogleDrive
50
86
  return orig_acl_feed_url
51
87
  when %r{^https?://docs.google.com/feeds/acl/private/full/([^\?]*)(\?.*)?$}
52
88
  # URL of old API version. Converts to v3 URL.
53
- return "https://docs.google.com/feeds/default/private/full/#{$1}/acl"
89
+ return "#{DOCS_BASE_URL}/#{$1}/acl"
54
90
  else
55
91
  raise(GoogleDrive::Error,
56
92
  "ACL feed URL is in unknown format: #{orig_acl_feed_url}")
@@ -149,8 +185,9 @@ module GoogleDrive
149
185
  # If +permanent+ is +false+, moves the file to the trash.
150
186
  # If +permanent+ is +true+, deletes the file permanently.
151
187
  def delete(permanent = false)
152
- @session.request(:delete,
153
- self.document_feed_url + (permanent ? "?delete=true" : ""),
188
+ url = to_v3_url(self.document_feed_url)
189
+ url = concat_url(url, "?delete=true") if permanent
190
+ @session.request(:delete, url,
154
191
  :auth => :writely, :header => {"If-Match" => "*"})
155
192
  end
156
193
 
@@ -180,7 +217,7 @@ module GoogleDrive
180
217
  # With the object, you can see and modify people who can access the file.
181
218
  # Modifications take effect immediately.
182
219
  #
183
- # Set <tt>params[:reload]</tt> to true to force reloading the title.
220
+ # Set <tt>params[:reload]</tt> to true to force reloading the data.
184
221
  #
185
222
  # e.g.
186
223
  # # Dumps people who have access:
@@ -209,7 +246,9 @@ module GoogleDrive
209
246
  end
210
247
 
211
248
  def inspect
212
- return "\#<%p document_feed_url=%p>" % [self.class, self.document_feed_url]
249
+ fields = {:document_feed_url => self.document_feed_url}
250
+ fields[:title] = self.title if @document_feed_entry
251
+ return "\#<%p %s>" % [self.class, fields.map(){ |k, v| "%s=%p" % [k, v] }.join(", ")]
213
252
  end
214
253
 
215
254
  end
@@ -97,6 +97,10 @@ module GoogleDrive
97
97
  return @worksheet[index + 2, key_to_col(key)]
98
98
  end
99
99
 
100
+ def numeric_value(index, key) #:nodoc:
101
+ return @worksheet.numeric_value(index + 2, key_to_col(key))
102
+ end
103
+
100
104
  def set(index, key, value) #:nodoc:
101
105
  @worksheet[index + 2, key_to_col(key)] = value
102
106
  end
@@ -29,6 +29,10 @@ module GoogleDrive
29
29
  return @list.get(@index, key)
30
30
  end
31
31
 
32
+ def numeric_value(key)
33
+ return @list.numeric_value(@index, key)
34
+ end
35
+
32
36
  def []=(key, value)
33
37
  @list.set(@index, key, value)
34
38
  end
@@ -35,9 +35,9 @@ module GoogleDrive
35
35
 
36
36
  def request_raw(method, url, data, extra_header, auth)
37
37
  if method == :delete || method == :get
38
- raw_res = @oauth2_token.request(method, url, {:header => extra_header})
38
+ raw_res = @oauth2_token.request(method, url, {:headers => extra_header})
39
39
  else
40
- raw_res = @oauth2_token.request(method, url, {:header => extra_header, :body => data})
40
+ raw_res = @oauth2_token.request(method, url, {:headers => extra_header, :body => data})
41
41
  end
42
42
  return Response.new(raw_res)
43
43
  end
@@ -112,12 +112,14 @@ module GoogleDrive
112
112
  # You can specify query parameters described at
113
113
  # https://developers.google.com/google-apps/documents-list/#getting_a_list_of_documents_and_files
114
114
  #
115
+ # files doesn't return collections unless "showfolders" => true is specified.
116
+ #
115
117
  # e.g.
116
118
  # session.files
117
119
  # session.files("title" => "hoge", "title-exact" => "true")
118
120
  def files(params = {})
119
121
  url = concat_url(
120
- "https://docs.google.com/feeds/default/private/full?v=3", "?" + encode_query(params))
122
+ "#{DOCS_BASE_URL}?v=3", "?" + encode_query(params))
121
123
  doc = request(:get, url, :auth => :writely)
122
124
  return doc.css("feed > entry").map(){ |e| entry_element_to_file(e) }
123
125
  end
@@ -200,7 +202,25 @@ module GoogleDrive
200
202
  def worksheet_by_url(url)
201
203
  return Worksheet.new(self, nil, url)
202
204
  end
203
-
205
+
206
+ # Returns the root collection.
207
+ def root_collection
208
+ return Collection.new(self, Collection::ROOT_URL)
209
+ end
210
+
211
+ # Returns the top-level collections (direct children of the root collection).
212
+ def collections
213
+ return self.root_collection.subcollections
214
+ end
215
+
216
+ # Returns a top-level collection whose title exactly matches +title+ as
217
+ # GoogleDrive::Collection.
218
+ # Returns nil if not found. If multiple collections with the +title+ are found, returns
219
+ # one of them.
220
+ def collection_by_title(title)
221
+ return self.root_collection.subcollection_by_title(title)
222
+ end
223
+
204
224
  # Returns GoogleDrive::Collection with given +url+.
205
225
  # You must specify either of:
206
226
  # - URL of the page you get when you go to https://docs.google.com/ with your browser and
@@ -219,7 +239,7 @@ module GoogleDrive
219
239
  if ["docs.google.com", "drive.google.com"].include?(uri.host) &&
220
240
  uri.fragment =~ /^folders\/(.+)$/
221
241
  # Looks like a URL of human-readable collection page. Converts to collection feed URL.
222
- url = "https://docs.google.com/feeds/default/private/full/folder%3A#{$1}"
242
+ url = "#{DOCS_BASE_URL}/folder%3A#{$1}"
223
243
  end
224
244
  return Collection.new(self, url)
225
245
  end
@@ -289,7 +309,7 @@ module GoogleDrive
289
309
  # Uploads a file. Reads content from +io+.
290
310
  # Returns a GoogleSpreadsheet::File object.
291
311
  def upload_from_io(io, title = "Untitled", params = {})
292
- doc = request(:get, "https://docs.google.com/feeds/default/private/full?v=3",
312
+ doc = request(:get, "#{DOCS_BASE_URL}?v=3",
293
313
  :auth => :writely)
294
314
  initial_url = doc.css(
295
315
  "link[rel='http://schemas.google.com/g/2005#resumable-create-media']")[0]["href"]
@@ -352,13 +372,17 @@ module GoogleDrive
352
372
  end
353
373
 
354
374
  def entry_element_to_file(entry) #:nodoc:
375
+ type, resource_id = entry.css("gd|resourceId").text.split(/:/)
355
376
  title = entry.css("title").text
356
- worksheets_feed_link = entry.css(
357
- "link[rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[0]
358
- if worksheets_feed_link
359
- return Spreadsheet.new(self, worksheets_feed_link["href"], title)
360
- else
361
- return GoogleDrive::File.new(self, entry)
377
+ case type
378
+ when "folder"
379
+ return Collection.new(self, entry)
380
+ when "spreadsheet"
381
+ worksheets_feed_link = entry.css(
382
+ "link[rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[0]
383
+ return Spreadsheet.new(self, worksheets_feed_link["href"], title)
384
+ else
385
+ return GoogleDrive::File.new(self, entry)
362
386
  end
363
387
  end
364
388
 
@@ -103,7 +103,6 @@ module GoogleDrive
103
103
  # Creates copy of this spreadsheet with the given title.
104
104
  def duplicate(new_title = nil)
105
105
  new_title ||= (self.title ? "Copy of " + self.title : "Untitled")
106
- post_url = "https://docs.google.com/feeds/default/private/full/"
107
106
  header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
108
107
  xml = <<-"EOS"
109
108
  <entry xmlns='http://www.w3.org/2005/Atom'>
@@ -112,7 +111,7 @@ module GoogleDrive
112
111
  </entry>
113
112
  EOS
114
113
  doc = @session.request(
115
- :post, post_url, :data => xml, :header => header, :auth => :writely)
114
+ :post, DOCS_BASE_URL, :data => xml, :header => header, :auth => :writely)
116
115
  ss_url = doc.css(
117
116
  "link[rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[0]["href"]
118
117
  return Spreadsheet.new(@session, ss_url, new_title)
@@ -7,6 +7,9 @@ require "cgi"
7
7
  module GoogleDrive
8
8
 
9
9
  module Util #:nodoc:
10
+
11
+ # The beginning of Doc List API URL that is used in all requests (version 3).
12
+ DOCS_BASE_URL = "https://docs.google.com/feeds/default/private/full"
10
13
 
11
14
  EXT_TO_CONTENT_TYPE = {
12
15
  ".csv" =>"text/csv",
@@ -45,7 +48,16 @@ module GoogleDrive
45
48
  (piece_base || "") +
46
49
  (result_query.empty? ? "" : "?#{result_query}")
47
50
  end
48
-
51
+
52
+ # Returns a URL with added version parameter ("?v=3") if needed.
53
+ def to_v3_url(url)
54
+ if url =~ %r{docs.google.com/feeds/default/private/} && !(url =~ /[?&]v=3/)
55
+ return concat_url(url, "?v=3")
56
+ else
57
+ return url
58
+ end
59
+ end
60
+
49
61
  def h(str)
50
62
  return CGI.escapeHTML(str.to_s())
51
63
  end
@@ -26,6 +26,7 @@ module GoogleDrive
26
26
 
27
27
  @cells = nil
28
28
  @input_values = nil
29
+ @numeric_values = nil
29
30
  @modified = Set.new()
30
31
  @list = nil
31
32
 
@@ -86,6 +87,7 @@ module GoogleDrive
86
87
  reload() if !@cells
87
88
  @cells[[row, col]] = value
88
89
  @input_values[[row, col]] = value
90
+ @numeric_values[[row, col]] = nil
89
91
  @modified.add([row, col])
90
92
  self.max_rows = row if row > @max_rows
91
93
  self.max_cols = col if col > @max_cols
@@ -116,6 +118,25 @@ module GoogleDrive
116
118
  return @input_values[[row, col]] || ""
117
119
  end
118
120
 
121
+ # Returns the numeric value of the cell. Arguments must be either
122
+ # (row number, column number) or cell name. Top-left cell is [1, 1].
123
+ #
124
+ # e.g.
125
+ # worksheet[1, 3] #=> "3,0" # it depends on locale, currency...
126
+ # worksheet.numeric_value(1, 3) #=> 3.0
127
+ #
128
+ # Returns nil if the cell is empty or contains non-number.
129
+ #
130
+ # If you modify the cell, its numeric_value is nil until you call save() and reload().
131
+ #
132
+ # For details, see:
133
+ # https://developers.google.com/google-apps/spreadsheets/#working_with_cell-based_feeds
134
+ def numeric_value(*args)
135
+ (row, col) = parse_cell_args(args)
136
+ reload() if !@cells
137
+ return @numeric_values[[row, col]]
138
+ end
139
+
119
140
  # Row number of the bottom-most non-empty row.
120
141
  def num_rows
121
142
  reload() if !@cells
@@ -176,8 +197,9 @@ module GoogleDrive
176
197
  end
177
198
 
178
199
  # An array of spreadsheet rows. Each row contains an array of
179
- # columns. Note that resulting array is 0-origin so
180
- # worksheet.rows[0][0] == worksheet[1, 1].
200
+ # columns. Note that resulting array is 0-origin so:
201
+ #
202
+ # worksheet.rows[0][0] == worksheet[1, 1]
181
203
  def rows(skip = 0)
182
204
  nc = self.num_cols
183
205
  result = ((1 + skip)..self.num_rows).map() do |row|
@@ -197,12 +219,15 @@ module GoogleDrive
197
219
 
198
220
  @cells = {}
199
221
  @input_values = {}
222
+ @numeric_values = {}
200
223
  doc.css("feed > entry").each() do |entry|
201
224
  cell = entry.css("gs|cell")[0]
202
225
  row = cell["row"].to_i()
203
226
  col = cell["col"].to_i()
204
227
  @cells[[row, col]] = cell.inner_text
205
228
  @input_values[[row, col]] = cell["inputValue"]
229
+ numeric_value = cell["numericValue"]
230
+ @numeric_values[[row, col]] = numeric_value ? numeric_value.to_f() : nil
206
231
  end
207
232
  @modified.clear()
208
233
  @meta_modified = false
@@ -433,10 +458,15 @@ module GoogleDrive
433
458
  if args.size == 1 && args[0].is_a?(String)
434
459
  return cell_name_to_row_col(args[0])
435
460
  elsif args.size == 2 && args[0].is_a?(Integer) && args[1].is_a?(Integer)
436
- return args
461
+ if args[0] >= 1 && args[1] >= 1
462
+ return args
463
+ else
464
+ raise(ArgumentError,
465
+ "Row/col must be >= 1 (1-origin), but are %d/%d" % [args[0], args[1]])
466
+ end
437
467
  else
438
468
  raise(ArgumentError,
439
- "Arguments must be either one String or two Integer's, but are %p" % args)
469
+ "Arguments must be either one String or two Integer's, but are %p" % [args])
440
470
  end
441
471
  end
442
472
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google_drive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-29 00:00:00.000000000 Z
12
+ date: 2012-07-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &77521180 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -27,10 +27,21 @@ dependencies:
27
27
  version: 1.5.2
28
28
  type: :runtime
29
29
  prerelease: false
30
- version_requirements: *77521180
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: 1.4.4
36
+ - - ! '!='
37
+ - !ruby/object:Gem::Version
38
+ version: 1.5.1
39
+ - - ! '!='
40
+ - !ruby/object:Gem::Version
41
+ version: 1.5.2
31
42
  - !ruby/object:Gem::Dependency
32
43
  name: oauth
33
- requirement: &77520430 !ruby/object:Gem::Requirement
44
+ requirement: !ruby/object:Gem::Requirement
34
45
  none: false
35
46
  requirements:
36
47
  - - ! '>='
@@ -38,10 +49,15 @@ dependencies:
38
49
  version: 0.3.6
39
50
  type: :runtime
40
51
  prerelease: false
41
- version_requirements: *77520430
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: 0.3.6
42
58
  - !ruby/object:Gem::Dependency
43
59
  name: oauth2
44
- requirement: &77520090 !ruby/object:Gem::Requirement
60
+ requirement: !ruby/object:Gem::Requirement
45
61
  none: false
46
62
  requirements:
47
63
  - - ! '>='
@@ -49,10 +65,15 @@ dependencies:
49
65
  version: 0.5.0
50
66
  type: :runtime
51
67
  prerelease: false
52
- version_requirements: *77520090
68
+ version_requirements: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: 0.5.0
53
74
  - !ruby/object:Gem::Dependency
54
75
  name: rake
55
- requirement: &77519770 !ruby/object:Gem::Requirement
76
+ requirement: !ruby/object:Gem::Requirement
56
77
  none: false
57
78
  requirements:
58
79
  - - ! '>='
@@ -60,7 +81,12 @@ dependencies:
60
81
  version: 0.8.0
61
82
  type: :development
62
83
  prerelease: false
63
- version_requirements: *77519770
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: 0.8.0
64
90
  description: A library to read/write files/spreadsheets in Google Drive/Docs.
65
91
  email:
66
92
  - gimite+github@gmail.com
@@ -114,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
140
  version: '0'
115
141
  requirements: []
116
142
  rubyforge_project:
117
- rubygems_version: 1.8.11
143
+ rubygems_version: 1.8.23
118
144
  signing_key:
119
145
  specification_version: 3
120
146
  summary: A library to read/write files/spreadsheets in Google Drive/Docs.