google-spreadsheet-ruby 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|