google-spreadsheet-ruby 0.1.1 → 0.1.2
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/lib/google_spreadsheet.rb +128 -94
- metadata +40 -15
data/lib/google_spreadsheet.rb
CHANGED
@@ -8,7 +8,8 @@ require "open-uri"
|
|
8
8
|
require "cgi"
|
9
9
|
require "uri"
|
10
10
|
require "rubygems"
|
11
|
-
require
|
11
|
+
require 'nokogiri'
|
12
|
+
|
12
13
|
require "oauth"
|
13
14
|
Net::HTTP.version_1_2
|
14
15
|
|
@@ -98,14 +99,6 @@ module GoogleSpreadsheet
|
|
98
99
|
return CGI.escapeHTML(str.to_s())
|
99
100
|
end
|
100
101
|
|
101
|
-
def as_utf8(str)
|
102
|
-
if str.respond_to?(:force_encoding)
|
103
|
-
str.force_encoding("UTF-8")
|
104
|
-
else
|
105
|
-
str
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
102
|
end
|
110
103
|
|
111
104
|
|
@@ -142,11 +135,8 @@ module GoogleSpreadsheet
|
|
142
135
|
|
143
136
|
# Restores session using return value of auth_tokens method of previous session.
|
144
137
|
def initialize(auth_tokens = nil, oauth_token = nil)
|
145
|
-
|
146
|
-
|
147
|
-
else
|
148
|
-
@auth_tokens = auth_tokens
|
149
|
-
end
|
138
|
+
@oauth_token = oauth_token
|
139
|
+
@auth_tokens = auth_tokens || {}
|
150
140
|
end
|
151
141
|
|
152
142
|
# Authenticates with given +mail+ and +password+, and updates current session object
|
@@ -176,10 +166,11 @@ module GoogleSpreadsheet
|
|
176
166
|
attr_accessor :on_auth_fail
|
177
167
|
|
178
168
|
def auth_header(auth) #:nodoc:
|
179
|
-
|
180
|
-
|
169
|
+
token = auth == :none ? nil : @auth_tokens[auth]
|
170
|
+
if token
|
171
|
+
return {"Authorization" => "GoogleLogin auth=#{token}"}
|
181
172
|
else
|
182
|
-
return {
|
173
|
+
return {}
|
183
174
|
end
|
184
175
|
end
|
185
176
|
|
@@ -194,10 +185,10 @@ module GoogleSpreadsheet
|
|
194
185
|
query = encode_query(params)
|
195
186
|
doc = request(:get, "https://spreadsheets.google.com/feeds/spreadsheets/private/full?#{query}")
|
196
187
|
result = []
|
197
|
-
|
198
|
-
title =
|
199
|
-
url =
|
200
|
-
"link[@rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[0]["href"]
|
188
|
+
doc.css("feed > entry").each() do |entry|
|
189
|
+
title = entry.css("title").text
|
190
|
+
url = entry.css(
|
191
|
+
"link[@rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[0]["href"]
|
201
192
|
result.push(Spreadsheet.new(self, url, title))
|
202
193
|
end
|
203
194
|
return result
|
@@ -260,68 +251,70 @@ module GoogleSpreadsheet
|
|
260
251
|
EOS
|
261
252
|
|
262
253
|
doc = request(:post, feed_url, :data => xml, :auth => :writely)
|
263
|
-
ss_url =
|
264
|
-
"link[@rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[
|
254
|
+
ss_url = doc.css(
|
255
|
+
"link[@rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']").first['href']
|
265
256
|
return Spreadsheet.new(self, ss_url, title)
|
266
257
|
end
|
267
258
|
|
268
259
|
def request(method, url, params = {}) #:nodoc:
|
269
260
|
# Always uses HTTPS.
|
270
|
-
|
261
|
+
url = url.gsub(%r{^http://}, "https://")
|
271
262
|
data = params[:data]
|
272
263
|
auth = params[:auth] || :wise
|
273
264
|
if params[:header]
|
274
|
-
|
265
|
+
extra_header = params[:header]
|
266
|
+
elsif data
|
267
|
+
extra_header = {"Content-Type" => "application/atom+xml"}
|
275
268
|
else
|
276
|
-
|
269
|
+
extra_header = {}
|
277
270
|
end
|
278
271
|
response_type = params[:response_type] || :xml
|
279
272
|
|
273
|
+
while true
|
274
|
+
response = request_raw(method, url, data, extra_header, auth)
|
275
|
+
if response.code == "401" && @on_auth_fail && @on_auth_fail.call()
|
276
|
+
next
|
277
|
+
end
|
278
|
+
if !(response.code =~ /^2/)
|
279
|
+
raise(
|
280
|
+
response.code == "401" ? AuthenticationError : GoogleSpreadsheet::Error,
|
281
|
+
"Response code #{response.code} for #{method} #{url}: " +
|
282
|
+
CGI.unescapeHTML(response.body))
|
283
|
+
end
|
284
|
+
return convert_response(response, response_type)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
private
|
289
|
+
|
290
|
+
def request_raw(method, url, data, extra_header, auth)
|
280
291
|
if @oauth_token
|
281
|
-
|
282
292
|
if method == :delete || method == :get
|
283
|
-
|
293
|
+
return @oauth_token.__send__(method, url, extra_header)
|
284
294
|
else
|
285
|
-
|
295
|
+
return @oauth_token.__send__(method, url, data, extra_header)
|
286
296
|
end
|
287
|
-
return convert_response(response, response_type)
|
288
|
-
|
289
297
|
else
|
290
|
-
|
298
|
+
uri = URI.parse(url)
|
291
299
|
http = Net::HTTP.new(uri.host, uri.port)
|
292
300
|
http.use_ssl = true
|
293
301
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
294
302
|
http.start() do
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
response = http.__send__(method, path, data, header)
|
302
|
-
end
|
303
|
-
if response.code == "401" && @on_auth_fail && @on_auth_fail.call()
|
304
|
-
next
|
305
|
-
end
|
306
|
-
if !(response.code =~ /^2/)
|
307
|
-
raise(
|
308
|
-
response.code == "401" ? AuthenticationError : GoogleSpreadsheet::Error,
|
309
|
-
"Response code #{response.code} for #{method} #{url}: " +
|
310
|
-
CGI.unescapeHTML(response.body))
|
311
|
-
end
|
312
|
-
return convert_response(response, response_type)
|
303
|
+
path = uri.path + (uri.query ? "?#{uri.query}" : "")
|
304
|
+
header = auth_header(auth).merge(extra_header)
|
305
|
+
if method == :delete || method == :get
|
306
|
+
return http.__send__(method, path, header)
|
307
|
+
else
|
308
|
+
return http.__send__(method, path, data, header)
|
313
309
|
end
|
314
310
|
end
|
315
|
-
|
316
311
|
end
|
317
312
|
end
|
318
313
|
|
319
|
-
private
|
320
|
-
|
321
314
|
def convert_response(response, response_type)
|
322
315
|
case response_type
|
323
316
|
when :xml
|
324
|
-
return
|
317
|
+
return Nokogiri.XML(response.body)
|
325
318
|
when :raw
|
326
319
|
return response.body
|
327
320
|
else
|
@@ -337,9 +330,10 @@ module GoogleSpreadsheet
|
|
337
330
|
"service" => auth.to_s(),
|
338
331
|
"source" => "Gimite-RubyGoogleSpreadsheet-1.00",
|
339
332
|
}
|
333
|
+
header = {"Content-Type" => "application/x-www-form-urlencoded"}
|
340
334
|
response = request(:post,
|
341
335
|
"https://www.google.com/accounts/ClientLogin",
|
342
|
-
:data => encode_query(params), :auth => :none, :header =>
|
336
|
+
:data => encode_query(params), :auth => :none, :header => header, :response_type => :raw)
|
343
337
|
@auth_tokens[auth] = response.slice(/^Auth=(.*)$/, 1)
|
344
338
|
end
|
345
339
|
|
@@ -378,12 +372,12 @@ module GoogleSpreadsheet
|
|
378
372
|
def tables_feed_url
|
379
373
|
return "https://spreadsheets.google.com/feeds/#{self.key}/tables"
|
380
374
|
end
|
381
|
-
|
375
|
+
|
382
376
|
# URL of feed used in document list feed API.
|
383
377
|
def document_feed_url
|
384
378
|
return "https://docs.google.com/feeds/documents/private/full/spreadsheet%3A#{self.key}"
|
385
379
|
end
|
386
|
-
|
380
|
+
|
387
381
|
# Creates copy of this spreadsheet with the given name.
|
388
382
|
def duplicate(new_name = nil)
|
389
383
|
new_name ||= (@title ? "Copy of " + @title : "Untitled")
|
@@ -396,8 +390,8 @@ module GoogleSpreadsheet
|
|
396
390
|
"Slug" => URI.encode(new_name),
|
397
391
|
}
|
398
392
|
doc = @session.request(:post, url, :data => ods, :auth => :writely, :header => header)
|
399
|
-
ss_url =
|
400
|
-
"link[@rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[
|
393
|
+
ss_url = doc.css(
|
394
|
+
"link[@rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']").first['href']
|
401
395
|
return Spreadsheet.new(@session, ss_url, title)
|
402
396
|
end
|
403
397
|
|
@@ -409,14 +403,32 @@ module GoogleSpreadsheet
|
|
409
403
|
:auth => :writely, :header => {"If-Match" => "*"})
|
410
404
|
end
|
411
405
|
|
406
|
+
# Renames title of the spreadsheet.
|
407
|
+
def rename(title)
|
408
|
+
doc = @session.request(:get, self.document_feed_url)
|
409
|
+
edit_url = doc.css("link[@rel='edit']").first['href']
|
410
|
+
xml = <<-"EOS"
|
411
|
+
<atom:entry
|
412
|
+
xmlns:atom="http://www.w3.org/2005/Atom"
|
413
|
+
xmlns:docs="http://schemas.google.com/docs/2007">
|
414
|
+
<atom:category
|
415
|
+
scheme="http://schemas.google.com/g/2005#kind"
|
416
|
+
term="http://schemas.google.com/docs/2007#spreadsheet" label="spreadsheet"/>
|
417
|
+
<atom:title>#{h(title)}</atom:title>
|
418
|
+
</atom:entry>
|
419
|
+
EOS
|
420
|
+
|
421
|
+
@session.request(:put, edit_url, :data => xml)
|
422
|
+
end
|
423
|
+
|
412
424
|
# Returns worksheets of the spreadsheet as array of GoogleSpreadsheet::Worksheet.
|
413
425
|
def worksheets
|
414
426
|
doc = @session.request(:get, @worksheets_feed_url)
|
415
427
|
result = []
|
416
|
-
|
417
|
-
title =
|
418
|
-
url =
|
419
|
-
"link[@rel='http://schemas.google.com/spreadsheets/2006#cellsfeed']")[
|
428
|
+
doc.css('entry').each() do |entry|
|
429
|
+
title = entry.css('title').text
|
430
|
+
url = entry.css(
|
431
|
+
"link[@rel='http://schemas.google.com/spreadsheets/2006#cellsfeed']").first['href']
|
420
432
|
result.push(Worksheet.new(@session, self, url, title))
|
421
433
|
end
|
422
434
|
return result.freeze()
|
@@ -433,15 +445,15 @@ module GoogleSpreadsheet
|
|
433
445
|
</entry>
|
434
446
|
EOS
|
435
447
|
doc = @session.request(:post, @worksheets_feed_url, :data => xml)
|
436
|
-
url =
|
437
|
-
"link[@rel='http://schemas.google.com/spreadsheets/2006#cellsfeed']")[
|
448
|
+
url = doc.css(
|
449
|
+
"link[@rel='http://schemas.google.com/spreadsheets/2006#cellsfeed']").first['href']
|
438
450
|
return Worksheet.new(@session, self, url, title)
|
439
451
|
end
|
440
452
|
|
441
453
|
# Returns list of tables in the spreadsheet.
|
442
454
|
def tables
|
443
455
|
doc = @session.request(:get, self.tables_feed_url)
|
444
|
-
return doc.
|
456
|
+
return doc.css('entry').map(){ |e| Table.new(@session, e) }.freeze()
|
445
457
|
end
|
446
458
|
|
447
459
|
end
|
@@ -454,8 +466,9 @@ module GoogleSpreadsheet
|
|
454
466
|
|
455
467
|
def initialize(session, entry) #:nodoc:
|
456
468
|
@columns = {}
|
457
|
-
@worksheet_title =
|
458
|
-
@records_url =
|
469
|
+
@worksheet_title = entry.css('gs|worksheet').first['name']
|
470
|
+
@records_url = entry.css("content")[0]["src"]
|
471
|
+
@edit_url = entry.css("link[@rel='edit']")[0]['href']
|
459
472
|
@session = session
|
460
473
|
end
|
461
474
|
|
@@ -465,7 +478,7 @@ module GoogleSpreadsheet
|
|
465
478
|
# Adds a record.
|
466
479
|
def add_record(values)
|
467
480
|
fields = ""
|
468
|
-
values.each do |name, value|
|
481
|
+
values.each() do |name, value|
|
469
482
|
fields += "<gs:field name='#{h(name)}'>#{h(value)}</gs:field>"
|
470
483
|
end
|
471
484
|
xml =<<-EOS
|
@@ -481,18 +494,24 @@ module GoogleSpreadsheet
|
|
481
494
|
# Returns records in the table.
|
482
495
|
def records
|
483
496
|
doc = @session.request(:get, @records_url)
|
484
|
-
return doc.
|
497
|
+
return doc.css('entry').map(){ |e| Record.new(@session, e) }
|
498
|
+
end
|
499
|
+
|
500
|
+
# Deletes this table. Deletion takes effect right away without calling save().
|
501
|
+
def delete
|
502
|
+
@session.request(:delete, @edit_url, :header => {"If-Match" => "*"})
|
485
503
|
end
|
486
504
|
|
487
505
|
end
|
488
506
|
|
489
507
|
# Use GoogleSpreadsheet::Table#records to get GoogleSpreadsheet::Record objects.
|
490
508
|
class Record < Hash
|
509
|
+
include(Util)
|
491
510
|
|
492
511
|
def initialize(session, entry) #:nodoc:
|
493
512
|
@session = session
|
494
|
-
|
495
|
-
self[
|
513
|
+
entry.css('gs|field').each() do |field|
|
514
|
+
self[field["name"]] = field.inner_text
|
496
515
|
end
|
497
516
|
end
|
498
517
|
|
@@ -652,18 +671,19 @@ module GoogleSpreadsheet
|
|
652
671
|
# Note that changes you made by []= is discarded if you haven't called save().
|
653
672
|
def reload()
|
654
673
|
doc = @session.request(:get, @cells_feed_url)
|
655
|
-
@max_rows = doc.
|
656
|
-
@max_cols = doc.
|
657
|
-
@title =
|
674
|
+
@max_rows = doc.css('gs|rowCount').text.to_i
|
675
|
+
@max_cols = doc.css('gs|colCount').text.to_i
|
676
|
+
@title = doc.css('feed > title')[0].text
|
658
677
|
|
659
678
|
@cells = {}
|
660
679
|
@input_values = {}
|
661
|
-
|
662
|
-
cell = entry.
|
680
|
+
doc.css('feed > entry').each() do |entry|
|
681
|
+
cell = entry.css('gs|cell').first
|
663
682
|
row = cell["row"].to_i()
|
664
683
|
col = cell["col"].to_i()
|
665
|
-
@cells[[row, col]] =
|
666
|
-
@input_values[[row, col]] =
|
684
|
+
@cells[[row, col]] = cell.inner_text
|
685
|
+
@input_values[[row, col]] = cell["inputValue"]
|
686
|
+
|
667
687
|
end
|
668
688
|
@modified.clear()
|
669
689
|
@meta_modified = false
|
@@ -677,7 +697,7 @@ module GoogleSpreadsheet
|
|
677
697
|
if @meta_modified
|
678
698
|
|
679
699
|
ws_doc = @session.request(:get, self.worksheet_feed_url)
|
680
|
-
edit_url = ws_doc.
|
700
|
+
edit_url = ws_doc.css("link[@rel='edit']").first['href']
|
681
701
|
xml = <<-"EOS"
|
682
702
|
<entry xmlns='http://www.w3.org/2005/Atom'
|
683
703
|
xmlns:gs='http://schemas.google.com/spreadsheets/2006'>
|
@@ -704,9 +724,10 @@ module GoogleSpreadsheet
|
|
704
724
|
url = "#{@cells_feed_url}?return-empty=true&min-row=#{rows.min}&max-row=#{rows.max}" +
|
705
725
|
"&min-col=#{cols.min}&max-col=#{cols.max}"
|
706
726
|
doc = @session.request(:get, url)
|
707
|
-
|
708
|
-
|
709
|
-
|
727
|
+
|
728
|
+
doc.css('entry').each() do |entry|
|
729
|
+
row = entry.css('gs|cell').first['row'].to_i
|
730
|
+
col = entry.css('gs|cell').first['col'].to_i
|
710
731
|
cell_entries[[row, col]] = entry
|
711
732
|
end
|
712
733
|
|
@@ -723,8 +744,8 @@ module GoogleSpreadsheet
|
|
723
744
|
for row, col in chunk
|
724
745
|
value = @cells[[row, col]]
|
725
746
|
entry = cell_entries[[row, col]]
|
726
|
-
id = entry.
|
727
|
-
edit_url = entry.
|
747
|
+
id = entry.css('id').text
|
748
|
+
edit_url = entry.css("link[@rel='edit']").first['href']
|
728
749
|
xml << <<-EOS
|
729
750
|
<entry>
|
730
751
|
<batch:id>#{h(row)},#{h(col)}</batch:id>
|
@@ -741,15 +762,15 @@ module GoogleSpreadsheet
|
|
741
762
|
EOS
|
742
763
|
|
743
764
|
result = @session.request(:post, "#{@cells_feed_url}/batch", :data => xml)
|
744
|
-
|
745
|
-
interrupted = entry.
|
765
|
+
result.css('atom|entry').each() do |entry|
|
766
|
+
interrupted = entry.css('batch|interrupted').first
|
746
767
|
if interrupted
|
747
768
|
raise(GoogleSpreadsheet::Error, "Update has failed: %s" %
|
748
769
|
interrupted["reason"])
|
749
770
|
end
|
750
|
-
if !(entry.
|
771
|
+
if !(entry.css('batch|status').first['code'] =~ /^2/)
|
751
772
|
raise(GoogleSpreadsheet::Error, "Updating cell %s has failed: %s" %
|
752
|
-
[entry.
|
773
|
+
[entry.css('atom|id').text, entry.css('batch|status').first['reason']])
|
753
774
|
end
|
754
775
|
end
|
755
776
|
|
@@ -771,7 +792,7 @@ module GoogleSpreadsheet
|
|
771
792
|
# Deletes this worksheet. Deletion takes effect right away without calling save().
|
772
793
|
def delete()
|
773
794
|
ws_doc = @session.request(:get, self.worksheet_feed_url)
|
774
|
-
edit_url = ws_doc.
|
795
|
+
edit_url = ws_doc.css("link[@rel='edit']").first['href']
|
775
796
|
@session.request(:delete, edit_url)
|
776
797
|
end
|
777
798
|
|
@@ -783,9 +804,12 @@ module GoogleSpreadsheet
|
|
783
804
|
# Creates table for the worksheet and returns GoogleSpreadsheet::Table.
|
784
805
|
# See this document for details:
|
785
806
|
# http://code.google.com/intl/en/apis/spreadsheets/docs/3.0/developers_guide_protocol.html#TableFeeds
|
786
|
-
def add_table(table_title, summary, columns)
|
807
|
+
def add_table(table_title, summary, columns, options)
|
808
|
+
default_options = { :header_row => 1, :num_rows => 0, :start_row => 2}
|
809
|
+
options = default_options.merge(options)
|
810
|
+
|
787
811
|
column_xml = ""
|
788
|
-
columns.each do |index, name|
|
812
|
+
columns.each() do |index, name|
|
789
813
|
column_xml += "<gs:column index='#{h(index)}' name='#{h(name)}'/>\n"
|
790
814
|
end
|
791
815
|
|
@@ -795,8 +819,8 @@ module GoogleSpreadsheet
|
|
795
819
|
<title type='text'>#{h(table_title)}</title>
|
796
820
|
<summary type='text'>#{h(summary)}</summary>
|
797
821
|
<gs:worksheet name='#{h(self.title)}' />
|
798
|
-
<gs:header row='
|
799
|
-
<gs:data numRows='
|
822
|
+
<gs:header row='#{options[:header_row]}' />
|
823
|
+
<gs:data numRows='#{options[:num_rows]}' startRow='#{options[:start_row]}'>
|
800
824
|
#{column_xml}
|
801
825
|
</gs:data>
|
802
826
|
</entry>
|
@@ -811,6 +835,16 @@ module GoogleSpreadsheet
|
|
811
835
|
return self.spreadsheet.tables.select(){ |t| t.worksheet_title == self.title }
|
812
836
|
end
|
813
837
|
|
838
|
+
# List feed URL of the worksheet.
|
839
|
+
def list_feed_url
|
840
|
+
# Gets the worksheets metafeed.
|
841
|
+
entry = @session.request(:get, self.worksheet_feed_url)
|
842
|
+
|
843
|
+
# Gets the URL of list-based feed for the given spreadsheet.
|
844
|
+
return entry.css(
|
845
|
+
"link[@rel='http://schemas.google.com/spreadsheets/2006#listfeed']").first['href']
|
846
|
+
end
|
847
|
+
|
814
848
|
end
|
815
849
|
|
816
850
|
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: google-spreadsheet-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 31
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Hiroshi Ichikawa
|
@@ -9,29 +15,42 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-09-24 00:00:00 +09:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
17
|
-
|
18
|
-
|
19
|
-
|
22
|
+
name: nokogiri
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - ">="
|
22
28
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
29
|
+
hash: 113
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 4
|
33
|
+
- 3
|
34
|
+
- 1
|
35
|
+
version: 1.4.3.1
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
25
38
|
- !ruby/object:Gem::Dependency
|
26
39
|
name: oauth
|
27
|
-
|
28
|
-
|
29
|
-
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
30
43
|
requirements:
|
31
44
|
- - ">="
|
32
45
|
- !ruby/object:Gem::Version
|
46
|
+
hash: 31
|
47
|
+
segments:
|
48
|
+
- 0
|
49
|
+
- 3
|
50
|
+
- 6
|
33
51
|
version: 0.3.6
|
34
|
-
|
52
|
+
type: :runtime
|
53
|
+
version_requirements: *id002
|
35
54
|
description: This is a library to read/write Google Spreadsheet.
|
36
55
|
email:
|
37
56
|
- gimite+github@gmail.com
|
@@ -55,21 +74,27 @@ rdoc_options:
|
|
55
74
|
require_paths:
|
56
75
|
- lib
|
57
76
|
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
58
78
|
requirements:
|
59
79
|
- - ">="
|
60
80
|
- !ruby/object:Gem::Version
|
81
|
+
hash: 3
|
82
|
+
segments:
|
83
|
+
- 0
|
61
84
|
version: "0"
|
62
|
-
version:
|
63
85
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
64
87
|
requirements:
|
65
88
|
- - ">="
|
66
89
|
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 0
|
67
93
|
version: "0"
|
68
|
-
version:
|
69
94
|
requirements: []
|
70
95
|
|
71
96
|
rubyforge_project:
|
72
|
-
rubygems_version: 1.3.
|
97
|
+
rubygems_version: 1.3.7
|
73
98
|
signing_key:
|
74
99
|
specification_version: 2
|
75
100
|
summary: This is a library to read/write Google Spreadsheet.
|