google-spreadsheet-ruby 0.2.1 → 0.3.0
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 +8 -55
- data/lib/google_spreadsheet.rb +3 -115
- data/lib/google_spreadsheet/acl.rb +1 -121
- data/lib/google_spreadsheet/acl_entry.rb +1 -55
- data/lib/google_spreadsheet/authentication_error.rb +1 -11
- data/lib/google_spreadsheet/client_login_fetcher.rb +1 -53
- data/lib/google_spreadsheet/collection.rb +1 -59
- data/lib/google_spreadsheet/error.rb +1 -9
- data/lib/google_spreadsheet/file.rb +4 -0
- data/lib/google_spreadsheet/list.rb +1 -112
- data/lib/google_spreadsheet/list_row.rb +1 -81
- data/lib/google_spreadsheet/oauth1_fetcher.rb +1 -23
- data/lib/google_spreadsheet/oauth2_fetcher.rb +1 -26
- data/lib/google_spreadsheet/record.rb +1 -28
- data/lib/google_spreadsheet/session.rb +1 -294
- data/lib/google_spreadsheet/spreadsheet.rb +1 -295
- data/lib/google_spreadsheet/table.rb +1 -57
- data/lib/google_spreadsheet/util.rb +1 -27
- data/lib/google_spreadsheet/worksheet.rb +1 -442
- metadata +21 -52
- data/doc_src/google_spreadsheet/acl.rb +0 -20
- data/doc_src/google_spreadsheet/acl_entry.rb +0 -33
@@ -1,62 +1,4 @@
|
|
1
1
|
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
2
|
# The license of this source is "New BSD Licence"
|
3
3
|
|
4
|
-
require "google_spreadsheet
|
5
|
-
require "google_spreadsheet/error"
|
6
|
-
require "google_spreadsheet/spreadsheet"
|
7
|
-
|
8
|
-
|
9
|
-
module GoogleSpreadsheet
|
10
|
-
|
11
|
-
# Use GoogleSpreadsheet::Session#collection_by_url to get GoogleSpreadsheet::Collection object.
|
12
|
-
class Collection
|
13
|
-
|
14
|
-
include(Util)
|
15
|
-
|
16
|
-
def initialize(session, collection_feed_url) #:nodoc:
|
17
|
-
@session = session
|
18
|
-
@collection_feed_url = collection_feed_url
|
19
|
-
end
|
20
|
-
|
21
|
-
attr_reader(:collection_feed_url)
|
22
|
-
|
23
|
-
# Adds the given GoogleSpreadsheet::Spreadsheet to the collection.
|
24
|
-
def add(spreadsheet)
|
25
|
-
contents_url = concat_url(@collection_feed_url, "/contents")
|
26
|
-
header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
|
27
|
-
xml = <<-"EOS"
|
28
|
-
<entry xmlns="http://www.w3.org/2005/Atom">
|
29
|
-
<id>#{h(spreadsheet.document_feed_url)}</id>
|
30
|
-
</entry>
|
31
|
-
EOS
|
32
|
-
@session.request(
|
33
|
-
:post, contents_url, :data => xml, :header => header, :auth => :writely)
|
34
|
-
return nil
|
35
|
-
end
|
36
|
-
|
37
|
-
# Returns all the spreadsheets in the collection.
|
38
|
-
def spreadsheets
|
39
|
-
|
40
|
-
contents_url = concat_url(@collection_feed_url, "/contents")
|
41
|
-
header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
|
42
|
-
doc = @session.request(:get, contents_url, :header => header, :auth => :writely)
|
43
|
-
|
44
|
-
result = []
|
45
|
-
for entry in doc.css("feed > entry")
|
46
|
-
title = entry.css("title").text
|
47
|
-
worksheets_feed_link = entry.css(
|
48
|
-
"link[rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[0]
|
49
|
-
if worksheets_feed_link
|
50
|
-
result.push(GoogleSpreadsheet::Spreadsheet.new(
|
51
|
-
@session, worksheets_feed_link["href"], title))
|
52
|
-
end
|
53
|
-
end
|
54
|
-
return result
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
# TODO Add other operations.
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
4
|
+
require "google_spreadsheet"
|
@@ -1,12 +1,4 @@
|
|
1
1
|
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
2
|
# The license of this source is "New BSD Licence"
|
3
3
|
|
4
|
-
|
5
|
-
module GoogleSpreadsheet
|
6
|
-
|
7
|
-
# Raised when spreadsheets.google.com has returned error.
|
8
|
-
class Error < RuntimeError
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
end
|
4
|
+
require "google_spreadsheet"
|
@@ -1,115 +1,4 @@
|
|
1
1
|
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
2
|
# The license of this source is "New BSD Licence"
|
3
3
|
|
4
|
-
require "google_spreadsheet
|
5
|
-
require "google_spreadsheet/error"
|
6
|
-
require "google_spreadsheet/list_row"
|
7
|
-
|
8
|
-
|
9
|
-
module GoogleSpreadsheet
|
10
|
-
|
11
|
-
# Provides access to cells using column names.
|
12
|
-
# Use GoogleSpreadsheet::Worksheet#list to get GoogleSpreadsheet::List object.
|
13
|
-
#--
|
14
|
-
# This is implemented as wrapper of GoogleSpreadsheet::Worksheet i.e. using cells
|
15
|
-
# feed, not list feed. In this way, we can easily provide consistent API as
|
16
|
-
# GoogleSpreadsheet::Worksheet using save()/reload().
|
17
|
-
class List
|
18
|
-
|
19
|
-
include(Enumerable)
|
20
|
-
|
21
|
-
def initialize(worksheet) #:nodoc:
|
22
|
-
@worksheet = worksheet
|
23
|
-
end
|
24
|
-
|
25
|
-
# Number of non-empty rows in the worksheet excluding the first row.
|
26
|
-
def size
|
27
|
-
return @worksheet.num_rows - 1
|
28
|
-
end
|
29
|
-
|
30
|
-
# Returns Hash-like object (GoogleSpreadsheet::ListRow) for the row with the
|
31
|
-
# index. Keys of the object are colum names (the first row).
|
32
|
-
# The second row has index 0.
|
33
|
-
#
|
34
|
-
# Note that updates to the returned object are not sent to the server until
|
35
|
-
# you call GoogleSpreadsheet::Worksheet#save().
|
36
|
-
def [](index)
|
37
|
-
return ListRow.new(self, index)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Updates the row with the index with the given Hash object.
|
41
|
-
# Keys of +hash+ are colum names (the first row).
|
42
|
-
# The second row has index 0.
|
43
|
-
#
|
44
|
-
# Note that update is not sent to the server until
|
45
|
-
# you call GoogleSpreadsheet::Worksheet#save().
|
46
|
-
def []=(index, hash)
|
47
|
-
self[index].replace(hash)
|
48
|
-
end
|
49
|
-
|
50
|
-
# Iterates over Hash-like object (GoogleSpreadsheet::ListRow) for each row
|
51
|
-
# (except for the first row).
|
52
|
-
# Keys of the object are colum names (the first row).
|
53
|
-
def each(&block)
|
54
|
-
for i in 0...self.size
|
55
|
-
yield(self[i])
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# Column names i.e. the contents of the first row.
|
60
|
-
# Duplicates are removed.
|
61
|
-
def keys
|
62
|
-
return (1..@worksheet.num_cols).map(){ |i| @worksheet[1, i] }.uniq()
|
63
|
-
end
|
64
|
-
|
65
|
-
# Updates column names i.e. the contents of the first row.
|
66
|
-
#
|
67
|
-
# Note that update is not sent to the server until
|
68
|
-
# you call GoogleSpreadsheet::Worksheet#save().
|
69
|
-
def keys=(ary)
|
70
|
-
for i in 1..ary.size
|
71
|
-
@worksheet[1, i] = ary[i - 1]
|
72
|
-
end
|
73
|
-
for i in (ary.size + 1)..@worksheet.num_cols
|
74
|
-
@worksheet[1, i] = ""
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
# Adds a new row to the bottom.
|
79
|
-
# Keys of +hash+ are colum names (the first row).
|
80
|
-
# Returns GoogleSpreadsheet::ListRow for the new row.
|
81
|
-
#
|
82
|
-
# Note that update is not sent to the server until
|
83
|
-
# you call GoogleSpreadsheet::Worksheet#save().
|
84
|
-
def push(hash)
|
85
|
-
row = self[self.size]
|
86
|
-
row.update(hash)
|
87
|
-
return row
|
88
|
-
end
|
89
|
-
|
90
|
-
# Returns all rows (except for the first row) as Array of Hash.
|
91
|
-
# Keys of Hash objects are colum names (the first row).
|
92
|
-
def to_hash_array()
|
93
|
-
return self.map(){ |r| r.to_hash() }
|
94
|
-
end
|
95
|
-
|
96
|
-
def get(index, key) #:nodoc:
|
97
|
-
return @worksheet[index + 2, key_to_col(key)]
|
98
|
-
end
|
99
|
-
|
100
|
-
def set(index, key, value) #:nodoc:
|
101
|
-
@worksheet[index + 2, key_to_col(key)] = value
|
102
|
-
end
|
103
|
-
|
104
|
-
private
|
105
|
-
|
106
|
-
def key_to_col(key)
|
107
|
-
key = key.to_s()
|
108
|
-
col = (1..@worksheet.num_cols).find(){ |c| @worksheet[1, c] == key }
|
109
|
-
raise(GoogleSpreadsheet::Error, "Colunm doesn't exist: %p" % key) if !col
|
110
|
-
return col
|
111
|
-
end
|
112
|
-
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
4
|
+
require "google_spreadsheet"
|
@@ -1,84 +1,4 @@
|
|
1
1
|
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
2
|
# The license of this source is "New BSD Licence"
|
3
3
|
|
4
|
-
require "
|
5
|
-
|
6
|
-
require "google_spreadsheet/util"
|
7
|
-
require "google_spreadsheet/error"
|
8
|
-
|
9
|
-
|
10
|
-
module GoogleSpreadsheet
|
11
|
-
|
12
|
-
# Hash-like object returned by GoogleSpreadsheet::List#[].
|
13
|
-
class ListRow
|
14
|
-
|
15
|
-
include(Enumerable)
|
16
|
-
extend(Forwardable)
|
17
|
-
|
18
|
-
def_delegators(:to_hash,
|
19
|
-
:keys, :values, :each_key, :each_value, :each, :each_pair, :hash,
|
20
|
-
:assoc, :fetch, :flatten, :key, :invert, :size, :length, :rassoc,
|
21
|
-
:merge, :reject, :select, :sort, :to_a, :values_at)
|
22
|
-
|
23
|
-
def initialize(list, index) #:nodoc:
|
24
|
-
@list = list
|
25
|
-
@index = index
|
26
|
-
end
|
27
|
-
|
28
|
-
def [](key)
|
29
|
-
return @list.get(@index, key)
|
30
|
-
end
|
31
|
-
|
32
|
-
def []=(key, value)
|
33
|
-
@list.set(@index, key, value)
|
34
|
-
end
|
35
|
-
|
36
|
-
def has_key?(key)
|
37
|
-
return @list.keys.include?(key)
|
38
|
-
end
|
39
|
-
|
40
|
-
alias include? has_key?
|
41
|
-
alias key? has_key?
|
42
|
-
alias member? has_key?
|
43
|
-
|
44
|
-
def update(hash)
|
45
|
-
for k, v in hash
|
46
|
-
self[k] = v
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
alias merge! update
|
51
|
-
|
52
|
-
def replace(hash)
|
53
|
-
clear()
|
54
|
-
update(hash)
|
55
|
-
end
|
56
|
-
|
57
|
-
def clear()
|
58
|
-
for key in @list.keys
|
59
|
-
self[key] = ""
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def to_hash()
|
64
|
-
result = {}
|
65
|
-
for key in @list.keys
|
66
|
-
result[key] = self[key]
|
67
|
-
end
|
68
|
-
return result
|
69
|
-
end
|
70
|
-
|
71
|
-
def ==(other)
|
72
|
-
return self.class == other.class && self.to_hash() == other.to_hash()
|
73
|
-
end
|
74
|
-
|
75
|
-
alias === ==
|
76
|
-
alias eql? ==
|
77
|
-
|
78
|
-
def inspect
|
79
|
-
return "\#<%p %p>" % [self.class, to_hash()]
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
4
|
+
require "google_spreadsheet"
|
@@ -1,26 +1,4 @@
|
|
1
1
|
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
2
|
# The license of this source is "New BSD Licence"
|
3
3
|
|
4
|
-
require "
|
5
|
-
require "oauth"
|
6
|
-
|
7
|
-
|
8
|
-
module GoogleSpreadsheet
|
9
|
-
|
10
|
-
class OAuth1Fetcher #:nodoc:
|
11
|
-
|
12
|
-
def initialize(oauth1_token)
|
13
|
-
@oauth1_token = oauth1_token
|
14
|
-
end
|
15
|
-
|
16
|
-
def request_raw(method, url, data, extra_header, auth)
|
17
|
-
if method == :delete || method == :get
|
18
|
-
return @oauth1_token.__send__(method, url, extra_header)
|
19
|
-
else
|
20
|
-
return @oauth1_token.__send__(method, url, data, extra_header)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
4
|
+
require "google_spreadsheet"
|
@@ -1,29 +1,4 @@
|
|
1
1
|
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
2
|
# The license of this source is "New BSD Licence"
|
3
3
|
|
4
|
-
require "
|
5
|
-
require "oauth2"
|
6
|
-
|
7
|
-
|
8
|
-
module GoogleSpreadsheet
|
9
|
-
|
10
|
-
class OAuth2Fetcher #:nodoc:
|
11
|
-
|
12
|
-
Response = Struct.new(:code, :body)
|
13
|
-
|
14
|
-
def initialize(oauth2_token)
|
15
|
-
@oauth2_token = oauth2_token
|
16
|
-
end
|
17
|
-
|
18
|
-
def request_raw(method, url, data, extra_header, auth)
|
19
|
-
if method == :delete || method == :get
|
20
|
-
raw_res = @oauth2_token.request(method, url, {:header => extra_header})
|
21
|
-
else
|
22
|
-
raw_res = @oauth2_token.request(method, url, {:header => extra_header, :body => data})
|
23
|
-
end
|
24
|
-
return Response.new(raw_res.status.to_s(), raw_res.body)
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
4
|
+
require "google_spreadsheet"
|
@@ -1,31 +1,4 @@
|
|
1
1
|
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
2
|
# The license of this source is "New BSD Licence"
|
3
3
|
|
4
|
-
require "google_spreadsheet
|
5
|
-
require "google_spreadsheet/error"
|
6
|
-
|
7
|
-
|
8
|
-
module GoogleSpreadsheet
|
9
|
-
|
10
|
-
# DEPRECATED: Table and Record feeds are deprecated and they will not be available after
|
11
|
-
# March 2012.
|
12
|
-
#
|
13
|
-
# Use GoogleSpreadsheet::Table#records to get GoogleSpreadsheet::Record objects.
|
14
|
-
class Record < Hash
|
15
|
-
include(Util)
|
16
|
-
|
17
|
-
def initialize(session, entry) #:nodoc:
|
18
|
-
@session = session
|
19
|
-
entry.css("gs|field").each() do |field|
|
20
|
-
self[field["name"]] = field.inner_text
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def inspect #:nodoc:
|
25
|
-
content = self.map(){ |k, v| "%p => %p" % [k, v] }.join(", ")
|
26
|
-
return "\#<%p:{%s}>" % [self.class, content]
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
4
|
+
require "google_spreadsheet"
|
@@ -1,297 +1,4 @@
|
|
1
1
|
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
2
|
# The license of this source is "New BSD Licence"
|
3
3
|
|
4
|
-
require "
|
5
|
-
|
6
|
-
require "rubygems"
|
7
|
-
require "nokogiri"
|
8
|
-
|
9
|
-
require "google_spreadsheet/util"
|
10
|
-
require "google_spreadsheet/client_login_fetcher"
|
11
|
-
require "google_spreadsheet/oauth1_fetcher"
|
12
|
-
require "google_spreadsheet/oauth2_fetcher"
|
13
|
-
require "google_spreadsheet/error"
|
14
|
-
require "google_spreadsheet/authentication_error"
|
15
|
-
require "google_spreadsheet/spreadsheet"
|
16
|
-
require "google_spreadsheet/worksheet"
|
17
|
-
require "google_spreadsheet/collection"
|
18
|
-
|
19
|
-
|
20
|
-
module GoogleSpreadsheet
|
21
|
-
|
22
|
-
# Use GoogleSpreadsheet.login or GoogleSpreadsheet.saved_session to get
|
23
|
-
# GoogleSpreadsheet::Session object.
|
24
|
-
class Session
|
25
|
-
|
26
|
-
include(Util)
|
27
|
-
extend(Util)
|
28
|
-
|
29
|
-
# The same as GoogleSpreadsheet.login.
|
30
|
-
def self.login(mail, password, proxy = nil)
|
31
|
-
session = Session.new(nil, ClientLoginFetcher.new({}, proxy))
|
32
|
-
session.login(mail, password)
|
33
|
-
return session
|
34
|
-
end
|
35
|
-
|
36
|
-
# The same as GoogleSpreadsheet.login_with_oauth.
|
37
|
-
def self.login_with_oauth(oauth_token)
|
38
|
-
case oauth_token
|
39
|
-
when OAuth::AccessToken
|
40
|
-
fetcher = OAuth1Fetcher.new(oauth_token)
|
41
|
-
when OAuth2::AccessToken
|
42
|
-
fetcher = OAuth2Fetcher.new(oauth_token)
|
43
|
-
else
|
44
|
-
raise(GoogleSpreadsheet::Error,
|
45
|
-
"oauth_token is neither OAuth::Token nor OAuth2::Token: %p" % oauth_token)
|
46
|
-
end
|
47
|
-
return Session.new(nil, fetcher)
|
48
|
-
end
|
49
|
-
|
50
|
-
# The same as GoogleSpreadsheet.restore_session.
|
51
|
-
def self.restore_session(auth_tokens, proxy = nil)
|
52
|
-
return Session.new(auth_tokens, nil, proxy)
|
53
|
-
end
|
54
|
-
|
55
|
-
# Creates a dummy GoogleSpreadsheet::Session object for testing.
|
56
|
-
def self.new_dummy()
|
57
|
-
return Session.new(nil, Object.new())
|
58
|
-
end
|
59
|
-
|
60
|
-
# DEPRECATED: Use GoogleSpreadsheet.restore_session instead.
|
61
|
-
def initialize(auth_tokens = nil, fetcher = nil, proxy = nil)
|
62
|
-
if fetcher
|
63
|
-
@fetcher = fetcher
|
64
|
-
else
|
65
|
-
@fetcher = ClientLoginFetcher.new(auth_tokens || {}, proxy)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# Authenticates with given +mail+ and +password+, and updates current session object
|
70
|
-
# if succeeds. Raises GoogleSpreadsheet::AuthenticationError if fails.
|
71
|
-
# Google Apps account is supported.
|
72
|
-
def login(mail, password)
|
73
|
-
if !@fetcher.is_a?(ClientLoginFetcher)
|
74
|
-
raise(GoogleSpreadsheet::Error,
|
75
|
-
"Cannot call login for session created by login_with_oauth.")
|
76
|
-
end
|
77
|
-
begin
|
78
|
-
@fetcher.auth_tokens = {
|
79
|
-
:wise => authenticate(mail, password, :wise),
|
80
|
-
:writely => authenticate(mail, password, :writely),
|
81
|
-
}
|
82
|
-
rescue GoogleSpreadsheet::Error => ex
|
83
|
-
return true if @on_auth_fail && @on_auth_fail.call()
|
84
|
-
raise(AuthenticationError, "Authentication failed for #{mail}: #{ex.message}")
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# Authentication tokens.
|
89
|
-
def auth_tokens
|
90
|
-
if !@fetcher.is_a?(ClientLoginFetcher)
|
91
|
-
raise(GoogleSpreadsheet::Error,
|
92
|
-
"Cannot call auth_tokens for session created by " +
|
93
|
-
"login_with_oauth.")
|
94
|
-
end
|
95
|
-
return @fetcher.auth_tokens
|
96
|
-
end
|
97
|
-
|
98
|
-
# Authentication token.
|
99
|
-
def auth_token(auth = :wise)
|
100
|
-
return self.auth_tokens[auth]
|
101
|
-
end
|
102
|
-
|
103
|
-
# Proc or Method called when authentication has failed.
|
104
|
-
# When this function returns +true+, it tries again.
|
105
|
-
attr_accessor :on_auth_fail
|
106
|
-
|
107
|
-
# Returns list of spreadsheets for the user as array of GoogleSpreadsheet::Spreadsheet.
|
108
|
-
# You can specify query parameters described at
|
109
|
-
# http://code.google.com/apis/spreadsheets/docs/2.0/reference.html#Parameters
|
110
|
-
#
|
111
|
-
# e.g.
|
112
|
-
# session.spreadsheets
|
113
|
-
# session.spreadsheets("title" => "hoge")
|
114
|
-
def spreadsheets(params = {})
|
115
|
-
query = encode_query(params)
|
116
|
-
doc = request(
|
117
|
-
:get, "https://spreadsheets.google.com/feeds/spreadsheets/private/full?#{query}")
|
118
|
-
result = []
|
119
|
-
doc.css("feed > entry").each() do |entry|
|
120
|
-
title = entry.css("title").text
|
121
|
-
url = entry.css(
|
122
|
-
"link[rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[0]["href"]
|
123
|
-
result.push(Spreadsheet.new(self, url, title))
|
124
|
-
end
|
125
|
-
return result
|
126
|
-
end
|
127
|
-
|
128
|
-
# Returns GoogleSpreadsheet::Spreadsheet with given +key+.
|
129
|
-
#
|
130
|
-
# e.g.
|
131
|
-
# # http://spreadsheets.google.com/ccc?key=pz7XtlQC-PYx-jrVMJErTcg&hl=ja
|
132
|
-
# session.spreadsheet_by_key("pz7XtlQC-PYx-jrVMJErTcg")
|
133
|
-
def spreadsheet_by_key(key)
|
134
|
-
url = "https://spreadsheets.google.com/feeds/worksheets/#{key}/private/full"
|
135
|
-
return Spreadsheet.new(self, url)
|
136
|
-
end
|
137
|
-
|
138
|
-
# Returns GoogleSpreadsheet::Spreadsheet with given +url+. You must specify either of:
|
139
|
-
# - URL of the page you open to access the spreadsheet in your browser
|
140
|
-
# - URL of worksheet-based feed of the spreadseet
|
141
|
-
#
|
142
|
-
# e.g.
|
143
|
-
# session.spreadsheet_by_url(
|
144
|
-
# "https://docs.google.com/spreadsheet/ccc?key=pz7XtlQC-PYx-jrVMJErTcg")
|
145
|
-
# session.spreadsheet_by_url(
|
146
|
-
# "https://spreadsheets.google.com/feeds/" +
|
147
|
-
# "worksheets/pz7XtlQC-PYx-jrVMJErTcg/private/full")
|
148
|
-
def spreadsheet_by_url(url)
|
149
|
-
# Tries to parse it as URL of human-readable spreadsheet.
|
150
|
-
uri = URI.parse(url)
|
151
|
-
if ["spreadsheets.google.com", "docs.google.com"].include?(uri.host) &&
|
152
|
-
uri.path =~ /\/ccc$/
|
153
|
-
if (uri.query || "").split(/&/).find(){ |s| s=~ /^key=(.*)$/ }
|
154
|
-
return spreadsheet_by_key($1)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
# Assumes the URL is worksheets feed URL.
|
158
|
-
return Spreadsheet.new(self, url)
|
159
|
-
end
|
160
|
-
|
161
|
-
# Returns GoogleSpreadsheet::Spreadsheet with given +title+.
|
162
|
-
# Returns nil if not found. If multiple spreadsheets with the +title+ are found, returns
|
163
|
-
# one of them.
|
164
|
-
def spreadsheet_by_title(title)
|
165
|
-
return spreadsheets({"title" => title})[0]
|
166
|
-
end
|
167
|
-
|
168
|
-
# Returns GoogleSpreadsheet::Worksheet with given +url+.
|
169
|
-
# You must specify URL of cell-based feed of the worksheet.
|
170
|
-
#
|
171
|
-
# e.g.
|
172
|
-
# session.worksheet_by_url(
|
173
|
-
# "http://spreadsheets.google.com/feeds/" +
|
174
|
-
# "cells/pz7XtlQC-PYxNmbBVgyiNWg/od6/private/full")
|
175
|
-
def worksheet_by_url(url)
|
176
|
-
return Worksheet.new(self, nil, url)
|
177
|
-
end
|
178
|
-
|
179
|
-
# Returns GoogleSpreadsheet::Collection with given +url+.
|
180
|
-
# You must specify either of:
|
181
|
-
# - URL of the page you get when you go to https://docs.google.com/ with your browser and
|
182
|
-
# open a collection
|
183
|
-
# - URL of collection (folder) feed
|
184
|
-
#
|
185
|
-
# e.g.
|
186
|
-
# session.collection_by_url(
|
187
|
-
# "https://docs.google.com/?pli=1&authuser=0#folders/" +
|
188
|
-
# "0B9GfDpQ2pBVUODNmOGE0NjIzMWU3ZC00NmUyLTk5NzEtYaFkZjY1MjAyxjMc")
|
189
|
-
# session.collection_by_url(
|
190
|
-
# "http://docs.google.com/feeds/default/private/full/folder%3A" +
|
191
|
-
# "0B9GfDpQ2pBVUODNmOGE0NjIzMWU3ZC00NmUyLTk5NzEtYaFkZjY1MjAyxjMc")
|
192
|
-
def collection_by_url(url)
|
193
|
-
uri = URI.parse(url)
|
194
|
-
if uri.host == "docs.google.com" && uri.fragment =~ /^folders\/(.+)$/
|
195
|
-
# Looks like a URL of human-readable collection page. Converts to collection feed URL.
|
196
|
-
url = "https://docs.google.com/feeds/default/private/full/folder%3A#{$1}"
|
197
|
-
end
|
198
|
-
return Collection.new(self, url)
|
199
|
-
end
|
200
|
-
|
201
|
-
# Creates new spreadsheet and returns the new GoogleSpreadsheet::Spreadsheet.
|
202
|
-
#
|
203
|
-
# e.g.
|
204
|
-
# session.create_spreadsheet("My new sheet")
|
205
|
-
def create_spreadsheet(
|
206
|
-
title = "Untitled",
|
207
|
-
feed_url = "https://docs.google.com/feeds/documents/private/full")
|
208
|
-
|
209
|
-
xml = <<-"EOS"
|
210
|
-
<atom:entry
|
211
|
-
xmlns:atom="http://www.w3.org/2005/Atom"
|
212
|
-
xmlns:docs="http://schemas.google.com/docs/2007">
|
213
|
-
<atom:category
|
214
|
-
scheme="http://schemas.google.com/g/2005#kind"
|
215
|
-
term="http://schemas.google.com/docs/2007#spreadsheet"
|
216
|
-
label="spreadsheet"/>
|
217
|
-
<atom:title>#{h(title)}</atom:title>
|
218
|
-
</atom:entry>
|
219
|
-
EOS
|
220
|
-
|
221
|
-
doc = request(:post, feed_url, :data => xml, :auth => :writely)
|
222
|
-
ss_url = doc.css(
|
223
|
-
"link[rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[0]["href"]
|
224
|
-
return Spreadsheet.new(self, ss_url, title)
|
225
|
-
|
226
|
-
end
|
227
|
-
|
228
|
-
def request(method, url, params = {}) #:nodoc:
|
229
|
-
|
230
|
-
# Always uses HTTPS.
|
231
|
-
url = url.gsub(%r{^http://}, "https://")
|
232
|
-
data = params[:data]
|
233
|
-
auth = params[:auth] || :wise
|
234
|
-
if params[:header]
|
235
|
-
extra_header = params[:header]
|
236
|
-
elsif data
|
237
|
-
extra_header = {"Content-Type" => "application/atom+xml"}
|
238
|
-
else
|
239
|
-
extra_header = {}
|
240
|
-
end
|
241
|
-
response_type = params[:response_type] || :xml
|
242
|
-
|
243
|
-
while true
|
244
|
-
response = @fetcher.request_raw(method, url, data, extra_header, auth)
|
245
|
-
if response.code == "401" && @on_auth_fail && @on_auth_fail.call()
|
246
|
-
next
|
247
|
-
end
|
248
|
-
if !(response.code =~ /^2/)
|
249
|
-
raise(
|
250
|
-
response.code == "401" ? AuthenticationError : GoogleSpreadsheet::Error,
|
251
|
-
"Response code #{response.code} for #{method} #{url}: " +
|
252
|
-
CGI.unescapeHTML(response.body))
|
253
|
-
end
|
254
|
-
return convert_response(response, response_type)
|
255
|
-
end
|
256
|
-
|
257
|
-
end
|
258
|
-
|
259
|
-
def inspect
|
260
|
-
return "#<%p:0x%x>" % [self.class, self.object_id]
|
261
|
-
end
|
262
|
-
|
263
|
-
private
|
264
|
-
|
265
|
-
def convert_response(response, response_type)
|
266
|
-
case response_type
|
267
|
-
when :xml
|
268
|
-
return Nokogiri.XML(response.body)
|
269
|
-
when :raw
|
270
|
-
return response.body
|
271
|
-
else
|
272
|
-
raise(GoogleSpreadsheet::Error,
|
273
|
-
"Unknown params[:response_type]: %s" % response_type)
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
def authenticate(mail, password, auth)
|
278
|
-
params = {
|
279
|
-
"accountType" => "HOSTED_OR_GOOGLE",
|
280
|
-
"Email" => mail,
|
281
|
-
"Passwd" => password,
|
282
|
-
"service" => auth.to_s(),
|
283
|
-
"source" => "Gimite-RubyGoogleSpreadsheet-1.00",
|
284
|
-
}
|
285
|
-
header = {"Content-Type" => "application/x-www-form-urlencoded"}
|
286
|
-
response = request(:post,
|
287
|
-
"https://www.google.com/accounts/ClientLogin",
|
288
|
-
:data => encode_query(params),
|
289
|
-
:auth => :none,
|
290
|
-
:header => header,
|
291
|
-
:response_type => :raw)
|
292
|
-
return response.slice(/^Auth=(.*)$/, 1)
|
293
|
-
end
|
294
|
-
|
295
|
-
end
|
296
|
-
|
297
|
-
end
|
4
|
+
require "google_spreadsheet"
|