Class: GoogleDrive::Session
- Inherits:
-
Object
- Object
- GoogleDrive::Session
- Extended by:
- Util
- Includes:
- Util
- Defined in:
- lib/google_drive/session.rb
Overview
Use GoogleDrive.login or GoogleDrive.saved_session to get GoogleDrive::Session object.
Constant Summary collapse
- UPLOAD_CHUNK_SIZE =
512 * 1024
Constants included from Util
Util::DOCS_BASE_URL, Util::EXT_TO_CONTENT_TYPE
Instance Attribute Summary collapse
-
#on_auth_fail ⇒ Object
Proc or Method called when authentication has failed.
Class Method Summary collapse
-
.login(mail, password, proxy = nil) ⇒ Object
The same as GoogleDrive.login.
-
.login_with_oauth(oauth_token) ⇒ Object
The same as GoogleDrive.login_with_oauth.
-
.new_dummy ⇒ Object
Creates a dummy GoogleDrive::Session object for testing.
-
.restore_session(auth_tokens, proxy = nil) ⇒ Object
The same as GoogleDrive.restore_session.
Instance Method Summary collapse
-
#auth_token(auth = :wise) ⇒ Object
Authentication token.
-
#auth_tokens ⇒ Object
Authentication tokens.
-
#collection_by_title(title) ⇒ Object
Returns a top-level collection whose title exactly matches
title
as GoogleDrive::Collection. -
#collection_by_url(url) ⇒ Object
Returns GoogleDrive::Collection with given
url
. -
#collections ⇒ Object
Returns the top-level collections (direct children of the root collection).
-
#create_spreadsheet(title = "Untitled", feed_url = "https://docs.google.com/feeds/documents/private/full") ⇒ Object
Creates new spreadsheet and returns the new GoogleDrive::Spreadsheet.
-
#entry_element_to_file(entry) ⇒ Object
:nodoc:.
-
#file_by_title(title) ⇒ Object
Returns GoogleDrive::File or its subclass whose title exactly matches
title
. -
#files(params = {}) ⇒ Object
Returns list of files for the user as array of GoogleDrive::File or its subclass.
-
#initialize(auth_tokens = nil, fetcher = nil, proxy = nil) ⇒ Session
constructor
DEPRECATED: Use GoogleDrive.restore_session instead.
- #inspect ⇒ Object
-
#login(mail, password) ⇒ Object
Authenticates with given
mail
andpassword
, and updates current session object if succeeds. -
#request(method, url, params = {}) ⇒ Object
:nodoc:.
-
#root_collection ⇒ Object
Returns the root collection.
-
#spreadsheet_by_key(key) ⇒ Object
Returns GoogleDrive::Spreadsheet with given
key
. -
#spreadsheet_by_title(title) ⇒ Object
Returns GoogleDrive::Spreadsheet with given
title
. -
#spreadsheet_by_url(url) ⇒ Object
Returns GoogleDrive::Spreadsheet with given
url
. -
#spreadsheets(params = {}) ⇒ Object
Returns list of spreadsheets for the user as array of GoogleDrive::Spreadsheet.
-
#upload_from_file(path, title = nil, params = {}) ⇒ Object
Uploads a local file.
-
#upload_from_io(io, title = "Untitled", params = {}) ⇒ Object
Uploads a file.
-
#upload_from_string(content, title = "Untitled", params = {}) ⇒ Object
Uploads a file with the given
title
andcontent
. -
#upload_raw(method, url, io, title = "Untitled", params = {}) ⇒ Object
:nodoc:.
-
#worksheet_by_url(url) ⇒ Object
Returns GoogleDrive::Worksheet with given
url
.
Methods included from Util
concat_url, encode_query, h, to_v3_url
Constructor Details
#initialize(auth_tokens = nil, fetcher = nil, proxy = nil) ⇒ Session
DEPRECATED: Use GoogleDrive.restore_session instead.
65 66 67 68 69 70 71 |
# File 'lib/google_drive/session.rb', line 65 def initialize(auth_tokens = nil, fetcher = nil, proxy = nil) if fetcher @fetcher = fetcher else @fetcher = ClientLoginFetcher.new(auth_tokens || {}, proxy) end end |
Instance Attribute Details
#on_auth_fail ⇒ Object
Proc or Method called when authentication has failed. When this function returns true
, it tries again.
109 110 111 |
# File 'lib/google_drive/session.rb', line 109 def on_auth_fail @on_auth_fail end |
Class Method Details
.login(mail, password, proxy = nil) ⇒ Object
The same as GoogleDrive.login.
34 35 36 37 38 |
# File 'lib/google_drive/session.rb', line 34 def self.login(mail, password, proxy = nil) session = Session.new(nil, ClientLoginFetcher.new({}, proxy)) session.login(mail, password) return session end |
.login_with_oauth(oauth_token) ⇒ Object
The same as GoogleDrive.login_with_oauth.
41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/google_drive/session.rb', line 41 def self.login_with_oauth(oauth_token) case oauth_token when OAuth::AccessToken fetcher = OAuth1Fetcher.new(oauth_token) when OAuth2::AccessToken fetcher = OAuth2Fetcher.new(oauth_token) else raise(GoogleDrive::Error, "oauth_token is neither OAuth::Token nor OAuth2::Token: %p" % oauth_token) end return Session.new(nil, fetcher) end |
Instance Method Details
#auth_token(auth = :wise) ⇒ Object
Authentication token.
103 104 105 |
# File 'lib/google_drive/session.rb', line 103 def auth_token(auth = :wise) return self.auth_tokens[auth] end |
#auth_tokens ⇒ Object
Authentication tokens.
93 94 95 96 97 98 99 100 |
# File 'lib/google_drive/session.rb', line 93 def auth_tokens if !@fetcher.is_a?(ClientLoginFetcher) raise(GoogleDrive::Error, "Cannot call auth_tokens for session created by " + "login_with_oauth.") end return @fetcher.auth_tokens end |
#collection_by_title(title) ⇒ Object
Returns a top-level collection whose title exactly matches title
as GoogleDrive::Collection. Returns nil if not found. If multiple collections with the title
are found, returns one of them.
220 221 222 |
# File 'lib/google_drive/session.rb', line 220 def collection_by_title(title) return self.root_collection.subcollection_by_title(title) end |
#collection_by_url(url) ⇒ Object
Returns GoogleDrive::Collection with given url
. You must specify either of:
-
URL of the page you get when you go to docs.google.com/ with your browser and open a collection
-
URL of collection (folder) feed
e.g.
session.collection_by_url(
"https://drive.google.com/#folders/" +
"0B9GfDpQ2pBVUODNmOGE0NjIzMWU3ZC00NmUyLTk5NzEtYaFkZjY1MjAyxjMc")
session.collection_by_url(
"http://docs.google.com/feeds/default/private/full/folder%3A" +
"0B9GfDpQ2pBVUODNmOGE0NjIzMWU3ZC00NmUyLTk5NzEtYaFkZjY1MjAyxjMc")
237 238 239 240 241 242 243 244 245 |
# File 'lib/google_drive/session.rb', line 237 def collection_by_url(url) uri = URI.parse(url) if ["docs.google.com", "drive.google.com"].include?(uri.host) && uri.fragment =~ /^folders\/(.+)$/ # Looks like a URL of human-readable collection page. Converts to collection feed URL. url = "#{DOCS_BASE_URL}/folder%3A#{$1}" end return Collection.new(self, url) end |
#collections ⇒ Object
Returns the top-level collections (direct children of the root collection).
212 213 214 |
# File 'lib/google_drive/session.rb', line 212 def collections return self.root_collection.subcollections end |
#create_spreadsheet(title = "Untitled", feed_url = "https://docs.google.com/feeds/documents/private/full") ⇒ Object
Creates new spreadsheet and returns the new GoogleDrive::Spreadsheet.
e.g.
session.create_spreadsheet("My new sheet")
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/google_drive/session.rb', line 251 def create_spreadsheet( title = "Untitled", feed_url = "https://docs.google.com/feeds/documents/private/full") xml = <<-"EOS" <atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007"> <atom:category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/docs/2007#spreadsheet" label="spreadsheet"/> <atom:title>#{h(title)}</atom:title> </atom:entry> EOS doc = request(:post, feed_url, :data => xml, :auth => :writely) ss_url = doc.css( "link[rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[0]["href"] return Spreadsheet.new(self, ss_url, title) end |
#entry_element_to_file(entry) ⇒ Object
:nodoc:
392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
# File 'lib/google_drive/session.rb', line 392 def entry_element_to_file(entry) #:nodoc: type, resource_id = entry.css("gd|resourceId").text.split(/:/) title = entry.css("title").text case type when "folder" return Collection.new(self, entry) when "spreadsheet" worksheets_feed_link = entry.css( "link[rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[0] return Spreadsheet.new(self, worksheets_feed_link["href"], title) else return GoogleDrive::File.new(self, entry) end end |
#file_by_title(title) ⇒ Object
Returns GoogleDrive::File or its subclass whose title exactly matches title
. Returns nil if not found. If multiple files with the title
are found, returns one of them.
130 131 132 |
# File 'lib/google_drive/session.rb', line 130 def file_by_title(title) return files("title" => title, "title-exact" => "true")[0] end |
#files(params = {}) ⇒ Object
Returns list of files for the user as array of GoogleDrive::File or its subclass. You can specify query parameters described at developers.google.com/google-apps/documents-list/#getting_a_list_of_documents_and_files
files doesn’t return collections unless “showfolders” => true is specified.
e.g.
session.files
session.files("title" => "hoge", "title-exact" => "true")
120 121 122 123 124 125 |
# File 'lib/google_drive/session.rb', line 120 def files(params = {}) url = concat_url( "#{DOCS_BASE_URL}?v=3", "?" + encode_query(params)) doc = request(:get, url, :auth => :writely) return doc.css("feed > entry").map(){ |e| entry_element_to_file(e) } end |
#inspect ⇒ Object
438 439 440 |
# File 'lib/google_drive/session.rb', line 438 def inspect return "#<%p:0x%x>" % [self.class, self.object_id] end |
#login(mail, password) ⇒ Object
Authenticates with given mail
and password
, and updates current session object if succeeds. Raises GoogleDrive::AuthenticationError if fails. Google Apps account is supported.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/google_drive/session.rb', line 76 def login(mail, password) if !@fetcher.is_a?(ClientLoginFetcher) raise(GoogleDrive::Error, "Cannot call login for session created by login_with_oauth.") end begin @fetcher.auth_tokens = { :wise => authenticate(mail, password, :wise), :writely => authenticate(mail, password, :writely), } rescue GoogleDrive::Error => ex return true if @on_auth_fail && @on_auth_fail.call() raise(AuthenticationError, "Authentication failed for #{mail}: #{ex.}") end end |
#request(method, url, params = {}) ⇒ Object
:nodoc:
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/google_drive/session.rb', line 407 def request(method, url, params = {}) #:nodoc: # Always uses HTTPS. url = url.gsub(%r{^http://}, "https://") data = params[:data] auth = params[:auth] || :wise if params[:header] extra_header = params[:header] elsif data extra_header = {"Content-Type" => "application/atom+xml"} else extra_header = {} end response_type = params[:response_type] || :xml while true response = @fetcher.request_raw(method, url, data, extra_header, auth) if response.code == "401" && @on_auth_fail && @on_auth_fail.call() next end if !(response.code =~ /^[23]/) raise( response.code == "401" ? AuthenticationError : GoogleDrive::Error, "Response code #{response.code} for #{method} #{url}: " + CGI.unescapeHTML(response.body)) end return convert_response(response, response_type) end end |
#root_collection ⇒ Object
Returns the root collection.
207 208 209 |
# File 'lib/google_drive/session.rb', line 207 def root_collection return Collection.new(self, Collection::ROOT_URL) end |
#spreadsheet_by_key(key) ⇒ Object
Returns GoogleDrive::Spreadsheet with given key
.
e.g.
# http://spreadsheets.google.com/ccc?key=pz7XtlQC-PYx-jrVMJErTcg&hl=ja
session.spreadsheet_by_key("pz7XtlQC-PYx-jrVMJErTcg")
160 161 162 163 |
# File 'lib/google_drive/session.rb', line 160 def spreadsheet_by_key(key) url = "https://spreadsheets.google.com/feeds/worksheets/#{key}/private/full" return Spreadsheet.new(self, url) end |
#spreadsheet_by_title(title) ⇒ Object
Returns GoogleDrive::Spreadsheet with given title
. Returns nil if not found. If multiple spreadsheets with the title
are found, returns one of them.
191 192 193 |
# File 'lib/google_drive/session.rb', line 191 def spreadsheet_by_title(title) return spreadsheets({"title" => title, "title-exact" => "true"})[0] end |
#spreadsheet_by_url(url) ⇒ Object
Returns GoogleDrive::Spreadsheet with given url
. You must specify either of:
-
URL of the page you open to access the spreadsheet in your browser
-
URL of worksheet-based feed of the spreadseet
e.g.
session.spreadsheet_by_url(
"https://docs.google.com/spreadsheet/ccc?key=pz7XtlQC-PYx-jrVMJErTcg")
session.spreadsheet_by_url(
"https://spreadsheets.google.com/feeds/" +
"worksheets/pz7XtlQC-PYx-jrVMJErTcg/private/full")
175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/google_drive/session.rb', line 175 def spreadsheet_by_url(url) # Tries to parse it as URL of human-readable spreadsheet. uri = URI.parse(url) if ["spreadsheets.google.com", "docs.google.com"].include?(uri.host) && uri.path =~ /\/ccc$/ if (uri.query || "").split(/&/).find(){ |s| s=~ /^key=(.*)$/ } return spreadsheet_by_key($1) end end # Assumes the URL is worksheets feed URL. return Spreadsheet.new(self, url) end |
#spreadsheets(params = {}) ⇒ Object
Returns list of spreadsheets for the user as array of GoogleDrive::Spreadsheet. You can specify query parameters e.g. “title”, “title-exact”.
e.g.
session.spreadsheets
session.spreadsheets("title" => "hoge")
session.spreadsheets("title" => "hoge", "title-exact" => "true")
141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/google_drive/session.rb', line 141 def spreadsheets(params = {}) query = encode_query(params) doc = request( :get, "https://spreadsheets.google.com/feeds/spreadsheets/private/full?#{query}") result = [] doc.css("feed > entry").each() do |entry| title = entry.css("title").text url = entry.css( "link[rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']")[0]["href"] result.push(Spreadsheet.new(self, url, title)) end return result end |
#upload_from_file(path, title = nil, params = {}) ⇒ Object
Uploads a local file. Returns a GoogleSpreadsheet::File object.
e.g.
# Uploads a text file and converts to a Google Docs document:
session.upload_from_file("/path/to/hoge.txt")
# Uploads without conversion:
session.upload_from_file("/path/to/hoge.txt", "Hoge", :convert => false)
# Uploads with explicit content type:
session.upload_from_file("/path/to/hoge", "Hoge", :content_type => "text/plain")
# Uploads a text file and converts to a Google Spreadsheet:
session.upload_from_file("/path/to/hoge.tsv", "Hoge")
session.upload_from_file("/path/to/hoge.csv", "Hoge")
session.upload_from_file("/path/to/hoge", "Hoge", :content_type => "text/tab-separated-values")
session.upload_from_file("/path/to/hoge", "Hoge", :content_type => "text/tsv")
311 312 313 314 315 316 317 |
# File 'lib/google_drive/session.rb', line 311 def upload_from_file(path, title = nil, params = {}) file_name = ::File.basename(path) params = {:file_name => file_name}.merge(params) open(path, "rb") do |f| return upload_from_io(f, title || file_name, params) end end |
#upload_from_io(io, title = "Untitled", params = {}) ⇒ Object
Uploads a file. Reads content from io
. Returns a GoogleSpreadsheet::File object.
321 322 323 324 325 326 327 |
# File 'lib/google_drive/session.rb', line 321 def upload_from_io(io, title = "Untitled", params = {}) doc = request(:get, "#{DOCS_BASE_URL}?v=3", :auth => :writely) initial_url = doc.css( "link[rel='http://schemas.google.com/g/2005#resumable-create-media']")[0]["href"] return upload_raw(:post, initial_url, io, title, params) end |
#upload_from_string(content, title = "Untitled", params = {}) ⇒ Object
Uploads a file with the given title
and content
. Returns a GoogleSpreadsheet::File object.
e.g.
# Uploads and converts to a Google Docs document:
session.upload_from_string(
"Hello world.", "Hello", :content_type => "text/plain")
# Uploads without conversion:
session.upload_from_string(
"Hello world.", "Hello", :content_type => "text/plain", :convert => false)
# Uploads and converts to a Google Spreadsheet:
session.upload_from_string("hoge\tfoo\n", "Hoge", :content_type => "text/tab-separated-values")
session.upload_from_string("hoge,foo\n", "Hoge", :content_type => "text/tsv")
289 290 291 |
# File 'lib/google_drive/session.rb', line 289 def upload_from_string(content, title = "Untitled", params = {}) return upload_from_io(StringIO.new(content), title, params) end |
#upload_raw(method, url, io, title = "Untitled", params = {}) ⇒ Object
:nodoc:
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 |
# File 'lib/google_drive/session.rb', line 329 def upload_raw(method, url, io, title = "Untitled", params = {}) #:nodoc: params = {:convert => true}.merge(params) pos = io.pos io.seek(0, IO::SEEK_END) total_bytes = io.pos - pos io.pos = pos content_type = params[:content_type] if !content_type && params[:file_name] content_type = EXT_TO_CONTENT_TYPE[::File.extname(params[:file_name]).downcase] end if !content_type content_type = "application/octet-stream" end initial_xml = <<-"EOS" <entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007"> <title>#{h(title)}</title> </entry> EOS default_initial_header = { "Content-Type" => "application/atom+xml", "X-Upload-Content-Type" => content_type, "X-Upload-Content-Length" => total_bytes.to_s(), } initial_full_url = concat_url(url, params[:convert] ? "?convert=true" : "?convert=false") initial_response = request(method, initial_full_url, :header => default_initial_header.merge(params[:header] || {}), :data => initial_xml, :auth => :writely, :response_type => :response) upload_url = initial_response["location"] if total_bytes > 0 sent_bytes = 0 while data = io.read(UPLOAD_CHUNK_SIZE) content_range = "bytes %d-%d/%d" % [ sent_bytes, sent_bytes + data.bytesize - 1, total_bytes, ] upload_header = { "Content-Type" => content_type, "Content-Range" => content_range, } doc = request( :put, upload_url, :header => upload_header, :data => data, :auth => :writely) sent_bytes += data.bytesize end else upload_header = { "Content-Type" => content_type, } doc = request( :put, upload_url, :header => upload_header, :data => "", :auth => :writely) end return entry_element_to_file(doc.root) end |
#worksheet_by_url(url) ⇒ Object
Returns GoogleDrive::Worksheet with given url
. You must specify URL of cell-based feed of the worksheet.
e.g.
session.worksheet_by_url(
"http://spreadsheets.google.com/feeds/" +
"cells/pz7XtlQC-PYxNmbBVgyiNWg/od6/private/full")
202 203 204 |
# File 'lib/google_drive/session.rb', line 202 def worksheet_by_url(url) return Worksheet.new(self, nil, url) end |