parallel588_google_drive 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +91 -0
- data/doc_src/google_drive/acl.rb +20 -0
- data/doc_src/google_drive/acl_entry.rb +33 -0
- data/lib/google_drive/acl.rb +115 -0
- data/lib/google_drive/acl_entry.rb +89 -0
- data/lib/google_drive/authentication_error.rb +14 -0
- data/lib/google_drive/client_login_fetcher.rb +56 -0
- data/lib/google_drive/collection.rb +139 -0
- data/lib/google_drive/error.rb +12 -0
- data/lib/google_drive/file.rb +251 -0
- data/lib/google_drive/list.rb +119 -0
- data/lib/google_drive/list_row.rb +88 -0
- data/lib/google_drive/oauth1_fetcher.rb +26 -0
- data/lib/google_drive/oauth2_fetcher.rb +47 -0
- data/lib/google_drive/record.rb +31 -0
- data/lib/google_drive/session.rb +485 -0
- data/lib/google_drive/spreadsheet.rb +227 -0
- data/lib/google_drive/table.rb +60 -0
- data/lib/google_drive/util.rb +68 -0
- data/lib/google_drive/worksheet.rb +475 -0
- data/lib/google_drive.rb +126 -0
- metadata +164 -0
@@ -0,0 +1,251 @@
|
|
1
|
+
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
|
+
# The license of this source is "New BSD Licence"
|
3
|
+
|
4
|
+
require "cgi"
|
5
|
+
require "stringio"
|
6
|
+
|
7
|
+
require "google_drive/util"
|
8
|
+
require "google_drive/acl"
|
9
|
+
|
10
|
+
|
11
|
+
module GoogleDrive
|
12
|
+
|
13
|
+
# A file in Google Drive, including Google Docs document/spreadsheet/presentation.
|
14
|
+
#
|
15
|
+
# Use GoogleDrive::Session#files or GoogleDrive::Session#file_by_title to
|
16
|
+
# get this object.
|
17
|
+
class File
|
18
|
+
|
19
|
+
include(Util)
|
20
|
+
|
21
|
+
def initialize(session, entry_or_url) #:nodoc:
|
22
|
+
@session = session
|
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?v=3" % [DOCS_BASE_URL, CGI.escape(self.resource_id)]
|
38
|
+
end
|
39
|
+
@acl = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
# URL of feed used in document list feed API.
|
43
|
+
attr_reader(:document_feed_url)
|
44
|
+
|
45
|
+
# <entry> element of document list feed as Nokogiri::XML::Element.
|
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
|
+
|
66
|
+
# Title of the file.
|
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
|
72
|
+
|
73
|
+
# URL to view/edit the file in a Web browser.
|
74
|
+
#
|
75
|
+
# e.g. "https://docs.google.com/file/d/xxxx/edit"
|
76
|
+
def human_url
|
77
|
+
return self.document_feed_entry.css("link[rel='alternate']")[0]["href"]
|
78
|
+
end
|
79
|
+
|
80
|
+
# ACL feed URL of the file.
|
81
|
+
def acl_feed_url
|
82
|
+
orig_acl_feed_url = self.document_feed_entry.css(
|
83
|
+
"gd|feedLink[rel='http://schemas.google.com/acl/2007#accessControlList']")[0]["href"]
|
84
|
+
case orig_acl_feed_url
|
85
|
+
when %r{^https?://docs.google.com/feeds/default/private/full/.*/acl(\?.*)?$}
|
86
|
+
return orig_acl_feed_url
|
87
|
+
when %r{^https?://docs.google.com/feeds/acl/private/full/([^\?]*)(\?.*)?$}
|
88
|
+
# URL of old API version. Converts to v3 URL.
|
89
|
+
return "#{DOCS_BASE_URL}/#{$1}/acl"
|
90
|
+
else
|
91
|
+
raise(GoogleDrive::Error,
|
92
|
+
"ACL feed URL is in unknown format: #{orig_acl_feed_url}")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Content types you can specify in methods download_to_file, download_to_string,
|
97
|
+
# download_to_io .
|
98
|
+
def available_content_types
|
99
|
+
return self.document_feed_entry.css("content").map(){ |c| c["type"] }
|
100
|
+
end
|
101
|
+
|
102
|
+
# Downloads the file to a local file.
|
103
|
+
#
|
104
|
+
# e.g.
|
105
|
+
# file.download_to_file("/path/to/hoge.txt")
|
106
|
+
# file.download_to_file("/path/to/hoge", :content_type => "text/plain")
|
107
|
+
def download_to_file(path, params = {})
|
108
|
+
params = params.dup()
|
109
|
+
if !params[:content_type]
|
110
|
+
params[:content_type] = EXT_TO_CONTENT_TYPE[::File.extname(path).downcase]
|
111
|
+
params[:content_type_is_hint] = true
|
112
|
+
end
|
113
|
+
open(path, "wb") do |f|
|
114
|
+
download_to_io(f, params)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Downloads the file and returns as a String.
|
119
|
+
#
|
120
|
+
# e.g.
|
121
|
+
# file.download_to_string() #=> "Hello world."
|
122
|
+
# file.download_to_string(:content_type => "text/plain") #=> "Hello world."
|
123
|
+
def download_to_string(params = {})
|
124
|
+
sio = StringIO.new()
|
125
|
+
download_to_io(sio, params)
|
126
|
+
return sio.string
|
127
|
+
end
|
128
|
+
|
129
|
+
# Downloads the file and writes it to +io+.
|
130
|
+
def download_to_io(io, params = {})
|
131
|
+
all_contents = self.document_feed_entry.css("content")
|
132
|
+
if params[:content_type] && (!params[:content_type_is_hint] || all_contents.size > 1)
|
133
|
+
contents = all_contents.select(){ |c| c["type"] == params[:content_type] }
|
134
|
+
else
|
135
|
+
contents = all_contents
|
136
|
+
end
|
137
|
+
if contents.size == 1
|
138
|
+
url = contents[0]["src"]
|
139
|
+
else
|
140
|
+
if contents.empty?
|
141
|
+
raise(GoogleDrive::Error,
|
142
|
+
("Downloading with content type %p not supported for this file. " +
|
143
|
+
"Specify one of these to content_type: %p") %
|
144
|
+
[params[:content_type], self.available_content_types])
|
145
|
+
else
|
146
|
+
raise(GoogleDrive::Error,
|
147
|
+
("Multiple content types are available for this file. " +
|
148
|
+
"Specify one of these to content_type: %p") %
|
149
|
+
[self.available_content_types])
|
150
|
+
end
|
151
|
+
end
|
152
|
+
# TODO Use streaming if possible.
|
153
|
+
body = @session.request(:get, url, :response_type => :raw, :auth => :writely)
|
154
|
+
io.write(body)
|
155
|
+
end
|
156
|
+
|
157
|
+
# Updates the file with the content of the local file.
|
158
|
+
#
|
159
|
+
# e.g.
|
160
|
+
# file.update_from_file("/path/to/hoge.txt")
|
161
|
+
def update_from_file(path, params = {})
|
162
|
+
params = {:file_name => ::File.basename(path)}.merge(params)
|
163
|
+
open(path, "rb") do |f|
|
164
|
+
update_from_io(f, params)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# Updates the file with +content+.
|
169
|
+
#
|
170
|
+
# e.g.
|
171
|
+
# file.update_from_string("Good bye, world.")
|
172
|
+
def update_from_string(content, params = {})
|
173
|
+
update_from_io(StringIO.new(content), params)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Reads content from +io+ and updates the file with the content.
|
177
|
+
def update_from_io(io, params = {})
|
178
|
+
params = {:header => {"If-Match" => "*"}}.merge(params)
|
179
|
+
initial_url = self.document_feed_entry.css(
|
180
|
+
"link[rel='http://schemas.google.com/g/2005#resumable-edit-media']")[0]["href"]
|
181
|
+
@document_feed_entry = @session.upload_raw(
|
182
|
+
:put, initial_url, io, self.title, params)
|
183
|
+
end
|
184
|
+
|
185
|
+
# If +permanent+ is +false+, moves the file to the trash.
|
186
|
+
# If +permanent+ is +true+, deletes the file permanently.
|
187
|
+
def delete(permanent = false)
|
188
|
+
url = to_v3_url(self.document_feed_url)
|
189
|
+
url = concat_url(url, "?delete=true") if permanent
|
190
|
+
@session.request(:delete, url,
|
191
|
+
:auth => :writely, :header => {"If-Match" => "*"})
|
192
|
+
end
|
193
|
+
|
194
|
+
# Renames title of the file.
|
195
|
+
def rename(title)
|
196
|
+
edit_url = self.document_feed_entry.css("link[rel='edit']").first["href"]
|
197
|
+
xml = <<-"EOS"
|
198
|
+
<atom:entry
|
199
|
+
xmlns:atom="http://www.w3.org/2005/Atom"
|
200
|
+
xmlns:docs="http://schemas.google.com/docs/2007">
|
201
|
+
<atom:title>#{h(title)}</atom:title>
|
202
|
+
</atom:entry>
|
203
|
+
EOS
|
204
|
+
header = {"Content-Type" => "application/atom+xml", "If-Match" => "*"}
|
205
|
+
@session.request(:put, edit_url, :data => xml, :auth => :writely, :header => header)
|
206
|
+
end
|
207
|
+
|
208
|
+
alias title= rename
|
209
|
+
|
210
|
+
# Returns GoogleDrive::Acl object for the file.
|
211
|
+
#
|
212
|
+
# With the object, you can see and modify people who can access the file.
|
213
|
+
# Modifications take effect immediately.
|
214
|
+
#
|
215
|
+
# Set <tt>params[:reload]</tt> to true to force reloading the data.
|
216
|
+
#
|
217
|
+
# e.g.
|
218
|
+
# # Dumps people who have access:
|
219
|
+
# for entry in file.acl
|
220
|
+
# p [entry.scope_type, entry.scope, entry.role]
|
221
|
+
# # => e.g. ["user", "example1@gmail.com", "owner"]
|
222
|
+
# end
|
223
|
+
#
|
224
|
+
# # Shares the file with new people:
|
225
|
+
# # NOTE: This sends email to the new people.
|
226
|
+
# file.acl.push(
|
227
|
+
# {:scope_type => "user", :scope => "example2@gmail.com", :role => "reader"})
|
228
|
+
# file.acl.push(
|
229
|
+
# {:scope_type => "user", :scope => "example3@gmail.com", :role => "writer"})
|
230
|
+
#
|
231
|
+
# # Changes the role of a person:
|
232
|
+
# file.acl[1].role = "writer"
|
233
|
+
#
|
234
|
+
# # Deletes an ACL entry:
|
235
|
+
# file.acl.delete(file.acl[1])
|
236
|
+
def acl(params = {})
|
237
|
+
if !@acl || params[:reload]
|
238
|
+
@acl = Acl.new(@session, self.acl_feed_url)
|
239
|
+
end
|
240
|
+
return @acl
|
241
|
+
end
|
242
|
+
|
243
|
+
def inspect
|
244
|
+
fields = {:document_feed_url => self.document_feed_url}
|
245
|
+
fields[:title] = self.title if @document_feed_entry
|
246
|
+
return "\#<%p %s>" % [self.class, fields.map(){ |k, v| "%s=%p" % [k, v] }.join(", ")]
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
|
+
# The license of this source is "New BSD Licence"
|
3
|
+
|
4
|
+
require "google_drive/util"
|
5
|
+
require "google_drive/error"
|
6
|
+
require "google_drive/list_row"
|
7
|
+
|
8
|
+
|
9
|
+
module GoogleDrive
|
10
|
+
|
11
|
+
# Provides access to cells using column names.
|
12
|
+
# Use GoogleDrive::Worksheet#list to get GoogleDrive::List object.
|
13
|
+
#--
|
14
|
+
# This is implemented as wrapper of GoogleDrive::Worksheet i.e. using cells
|
15
|
+
# feed, not list feed. In this way, we can easily provide consistent API as
|
16
|
+
# GoogleDrive::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 (GoogleDrive::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 GoogleDrive::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 GoogleDrive::Worksheet#save().
|
46
|
+
def []=(index, hash)
|
47
|
+
self[index].replace(hash)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Iterates over Hash-like object (GoogleDrive::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 GoogleDrive::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 GoogleDrive::ListRow for the new row.
|
81
|
+
#
|
82
|
+
# Note that update is not sent to the server until
|
83
|
+
# you call GoogleDrive::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 numeric_value(index, key) #:nodoc:
|
101
|
+
return @worksheet.numeric_value(index + 2, key_to_col(key))
|
102
|
+
end
|
103
|
+
|
104
|
+
def set(index, key, value) #:nodoc:
|
105
|
+
@worksheet[index + 2, key_to_col(key)] = value
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def key_to_col(key)
|
111
|
+
key = key.to_s()
|
112
|
+
col = (1..@worksheet.num_cols).find(){ |c| @worksheet[1, c] == key }
|
113
|
+
raise(GoogleDrive::Error, "Column doesn't exist: %p" % key) if !col
|
114
|
+
return col
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
|
+
# The license of this source is "New BSD Licence"
|
3
|
+
|
4
|
+
require "forwardable"
|
5
|
+
|
6
|
+
require "google_drive/util"
|
7
|
+
require "google_drive/error"
|
8
|
+
|
9
|
+
|
10
|
+
module GoogleDrive
|
11
|
+
|
12
|
+
# Hash-like object returned by GoogleDrive::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 numeric_value(key)
|
33
|
+
return @list.numeric_value(@index, key)
|
34
|
+
end
|
35
|
+
|
36
|
+
def []=(key, value)
|
37
|
+
@list.set(@index, key, value)
|
38
|
+
end
|
39
|
+
|
40
|
+
def has_key?(key)
|
41
|
+
return @list.keys.include?(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
alias include? has_key?
|
45
|
+
alias key? has_key?
|
46
|
+
alias member? has_key?
|
47
|
+
|
48
|
+
def update(hash)
|
49
|
+
for k, v in hash
|
50
|
+
self[k] = v
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
alias merge! update
|
55
|
+
|
56
|
+
def replace(hash)
|
57
|
+
clear()
|
58
|
+
update(hash)
|
59
|
+
end
|
60
|
+
|
61
|
+
def clear()
|
62
|
+
for key in @list.keys
|
63
|
+
self[key] = ""
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_hash()
|
68
|
+
result = {}
|
69
|
+
for key in @list.keys
|
70
|
+
result[key] = self[key]
|
71
|
+
end
|
72
|
+
return result
|
73
|
+
end
|
74
|
+
|
75
|
+
def ==(other)
|
76
|
+
return self.class == other.class && self.to_hash() == other.to_hash()
|
77
|
+
end
|
78
|
+
|
79
|
+
alias === ==
|
80
|
+
alias eql? ==
|
81
|
+
|
82
|
+
def inspect
|
83
|
+
return "\#<%p %p>" % [self.class, to_hash()]
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
|
+
# The license of this source is "New BSD Licence"
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "oauth"
|
6
|
+
|
7
|
+
|
8
|
+
module GoogleDrive
|
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
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
|
+
# The license of this source is "New BSD Licence"
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "oauth2"
|
6
|
+
|
7
|
+
|
8
|
+
module GoogleDrive
|
9
|
+
|
10
|
+
class OAuth2Fetcher #:nodoc:
|
11
|
+
|
12
|
+
class Response
|
13
|
+
|
14
|
+
def initialize(raw_res)
|
15
|
+
@raw_res = raw_res
|
16
|
+
end
|
17
|
+
|
18
|
+
def code
|
19
|
+
return @raw_res.status.to_s()
|
20
|
+
end
|
21
|
+
|
22
|
+
def body
|
23
|
+
return @raw_res.body
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](name)
|
27
|
+
return @raw_res.headers[name]
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(oauth2_token)
|
33
|
+
@oauth2_token = oauth2_token
|
34
|
+
end
|
35
|
+
|
36
|
+
def request_raw(method, url, data, extra_header, auth)
|
37
|
+
if method == :delete || method == :get
|
38
|
+
raw_res = @oauth2_token.request(method, url, {:headers => extra_header})
|
39
|
+
else
|
40
|
+
raw_res = @oauth2_token.request(method, url, {:headers => extra_header, :body => data})
|
41
|
+
end
|
42
|
+
return Response.new(raw_res)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
|
+
# The license of this source is "New BSD Licence"
|
3
|
+
|
4
|
+
require "google_drive/util"
|
5
|
+
require "google_drive/error"
|
6
|
+
|
7
|
+
|
8
|
+
module GoogleDrive
|
9
|
+
|
10
|
+
# DEPRECATED: Table and Record feeds are deprecated and they will not be available after
|
11
|
+
# March 2012.
|
12
|
+
#
|
13
|
+
# Use GoogleDrive::Table#records to get GoogleDrive::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
|