Class: GoogleDriveV0::Session
- Inherits:
-
Object
- Object
- GoogleDriveV0::Session
- Extended by:
- Util
- Includes:
- Util
- Defined in:
- lib/google_drive_v0/session.rb
Overview
Use GoogleDriveV0.login or GoogleDriveV0.saved_session to get GoogleDriveV0::Session object.
Constant Summary collapse
- UPLOAD_CHUNK_SIZE =
512 * 1024
Constants included from Util
Util::DOCS_BASE_URL, Util::EXT_TO_CONTENT_TYPE
Class Method Summary collapse
-
.login(mail, password, proxy = nil) ⇒ Object
DEPRECATED: Will be removed in the next version.
-
.login_with_oauth(access_token, proxy = nil) ⇒ Object
The same as GoogleDriveV0.login_with_oauth.
-
.new_dummy ⇒ Object
Creates a dummy GoogleDriveV0::Session object for testing.
-
.restore_session(auth_tokens, proxy = nil) ⇒ Object
The same as GoogleDriveV0.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 GoogleDriveV0::Collection. -
#collection_by_url(url) ⇒ Object
Returns GoogleDriveV0::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 GoogleDriveV0::Spreadsheet.
-
#entry_element_to_file(entry) ⇒ Object
:nodoc:.
-
#file_by_title(title) ⇒ Object
Returns GoogleDriveV0::File or its subclass whose title exactly matches
title
. -
#files(params = {}) ⇒ Object
Returns list of files for the user as array of GoogleDriveV0::File or its subclass.
-
#initialize(auth_tokens = nil, fetcher = nil, proxy = nil) ⇒ Session
constructor
DEPRECATED: Use GoogleDriveV0.restore_session instead.
- #inspect ⇒ Object
-
#login(mail, password) ⇒ Object
Authenticates with given
mail
andpassword
, and updates current session object if succeeds. -
#on_auth_fail ⇒ Object
Proc or Method called when authentication has failed.
- #on_auth_fail=(func) ⇒ Object
-
#request(method, url, params = {}) ⇒ Object
:nodoc:.
-
#root_collection ⇒ Object
Returns the root collection.
-
#spreadsheet_by_key(key) ⇒ Object
Returns GoogleDriveV0::Spreadsheet with given
key
. -
#spreadsheet_by_title(title) ⇒ Object
Returns GoogleDriveV0::Spreadsheet with given
title
. -
#spreadsheet_by_url(url) ⇒ Object
Returns GoogleDriveV0::Spreadsheet with given
url
. -
#spreadsheets(params = {}) ⇒ Object
Returns list of spreadsheets for the user as array of GoogleDriveV0::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 GoogleDriveV0::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 GoogleDriveV0.restore_session instead.
86 87 88 89 90 91 92 |
# File 'lib/google_drive_v0/session.rb', line 86 def initialize(auth_tokens = nil, fetcher = nil, proxy = nil) if fetcher @fetcher = fetcher else @fetcher = ClientLoginFetcher.new(auth_tokens || {}, proxy) end end |
Class Method Details
.login(mail, password, proxy = nil) ⇒ Object
DEPRECATED: Will be removed in the next version.
The same as GoogleDriveV0.login.
38 39 40 41 42 43 44 45 |
# File 'lib/google_drive_v0/session.rb', line 38 def self.login(mail, password, proxy = nil) warn( "WARNING: GoogleDriveV0.login is deprecated and will be removed in the next version. " + "Use GoogleDriveV0.login_with_oauth instead.") session = Session.new(nil, ClientLoginFetcher.new({}, proxy)) session.login(mail, password) return session end |
.login_with_oauth(access_token, proxy = nil) ⇒ Object
The same as GoogleDriveV0.login_with_oauth.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/google_drive_v0/session.rb', line 48 def self.login_with_oauth(access_token, proxy = nil) if proxy warn( "WARNING: Specifying a proxy object is deprecated and will not work in the next version. " + "Set ENV[\"http_proxy\"] instead.") end case access_token when OAuth::AccessToken warn( "WARNING: Authorization with OAuth1 is deprecated and will not work in the next version. " + "Use OAuth2 instead.") raise(GoogleDriveV0::Error, "proxy is not supported with OAuth1.") if proxy fetcher = OAuth1Fetcher.new(access_token) when OAuth2::AccessToken fetcher = OAuth2Fetcher.new(access_token.token, proxy) when String fetcher = OAuth2Fetcher.new(access_token, proxy) else raise(GoogleDriveV0::Error, "access_token is neither String, OAuth2::Token nor OAuth::Token: %p" % access_token) end return Session.new(nil, fetcher) end |
.new_dummy ⇒ Object
Creates a dummy GoogleDriveV0::Session object for testing.
81 82 83 |
# File 'lib/google_drive_v0/session.rb', line 81 def self.new_dummy() return Session.new(nil, Object.new()) end |
.restore_session(auth_tokens, proxy = nil) ⇒ Object
The same as GoogleDriveV0.restore_session.
73 74 75 76 77 78 |
# File 'lib/google_drive_v0/session.rb', line 73 def self.restore_session(auth_tokens, proxy = nil) warn( "WARNING: GoogleDriveV0.restore_session is deprecated and will be removed in the next version. " + "Use GoogleDriveV0.login_with_oauth instead.") return Session.new(auth_tokens, nil, proxy) end |
Instance Method Details
#auth_token(auth = :wise) ⇒ Object
Authentication token.
126 127 128 129 130 |
# File 'lib/google_drive_v0/session.rb', line 126 def auth_token(auth = :wise) warn( "WARNING: GoogleDriveV0::Session\#auth_token is deprecated and will be removed in the next version.") return self.auth_tokens[auth] end |
#auth_tokens ⇒ Object
Authentication tokens.
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/google_drive_v0/session.rb', line 114 def auth_tokens warn( "WARNING: GoogleDriveV0::Session\#auth_tokens is deprecated and will be removed in the next version.") if !@fetcher.is_a?(ClientLoginFetcher) raise(GoogleDriveV0::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 GoogleDriveV0::Collection. Returns nil if not found. If multiple collections with the title
are found, returns one of them.
263 264 265 |
# File 'lib/google_drive_v0/session.rb', line 263 def collection_by_title(title) return self.root_collection.subcollection_by_title(title) end |
#collection_by_url(url) ⇒ Object
Returns GoogleDriveV0::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")
280 281 282 283 284 285 286 287 288 |
# File 'lib/google_drive_v0/session.rb', line 280 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, to_v3_url(url)) end |
#collections ⇒ Object
Returns the top-level collections (direct children of the root collection).
255 256 257 |
# File 'lib/google_drive_v0/session.rb', line 255 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 GoogleDriveV0::Spreadsheet.
e.g.
session.create_spreadsheet("My new sheet")
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/google_drive_v0/session.rb', line 294 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:
436 437 438 439 440 441 442 443 444 445 446 447 448 449 |
# File 'lib/google_drive_v0/session.rb', line 436 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 GoogleDriveV0::File.new(self, entry) end end |
#file_by_title(title) ⇒ Object
Returns GoogleDriveV0::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.
If given an Array, traverses collections by title. e.g.
session.file_by_title(["myfolder", "mysubfolder/even/w/slash", "myfile"])
168 169 170 171 172 173 174 |
# File 'lib/google_drive_v0/session.rb', line 168 def file_by_title(title) if title.is_a?(Array) return self.root_collection.file_by_title(title) else return files("title" => title, "title-exact" => "true")[0] end end |
#files(params = {}) ⇒ Object
Returns list of files for the user as array of GoogleDriveV0::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")
155 156 157 158 159 160 |
# File 'lib/google_drive_v0/session.rb', line 155 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
482 483 484 |
# File 'lib/google_drive_v0/session.rb', line 482 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 GoogleDriveV0::AuthenticationError if fails. Google Apps account is supported.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/google_drive_v0/session.rb', line 97 def login(mail, password) if !@fetcher.is_a?(ClientLoginFetcher) raise(GoogleDriveV0::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 GoogleDriveV0::Error => ex return true if @on_auth_fail && @on_auth_fail.call() raise(AuthenticationError, "Authentication failed for #{mail}: #{ex.}") end end |
#on_auth_fail ⇒ Object
Proc or Method called when authentication has failed. When this function returns true
, it tries again.
134 135 136 137 138 |
# File 'lib/google_drive_v0/session.rb', line 134 def on_auth_fail warn( "WARNING: GoogleDriveV0::Session\#on_auth_fail is deprecated and will be removed in the next version.") return @on_auth_fail end |
#on_auth_fail=(func) ⇒ Object
140 141 142 143 144 |
# File 'lib/google_drive_v0/session.rb', line 140 def on_auth_fail=(func) warn( "WARNING: GoogleDriveV0::Session\#on_auth_fail is deprecated and will be removed in the next version.") @on_auth_fail = func end |
#request(method, url, params = {}) ⇒ Object
:nodoc:
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 |
# File 'lib/google_drive_v0/session.rb', line 451 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;charset=utf-8"} 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 : GoogleDriveV0::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.
250 251 252 |
# File 'lib/google_drive_v0/session.rb', line 250 def root_collection return Collection.new(self, Collection::ROOT_URL) end |
#spreadsheet_by_key(key) ⇒ Object
Returns GoogleDriveV0::Spreadsheet with given key
.
e.g.
# http://spreadsheets.google.com/ccc?key=pz7XtlQC-PYx-jrVMJErTcg&hl=ja
session.spreadsheet_by_key("pz7XtlQC-PYx-jrVMJErTcg")
199 200 201 202 |
# File 'lib/google_drive_v0/session.rb', line 199 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 GoogleDriveV0::Spreadsheet with given title
. Returns nil if not found. If multiple spreadsheets with the title
are found, returns one of them.
234 235 236 |
# File 'lib/google_drive_v0/session.rb', line 234 def spreadsheet_by_title(title) return spreadsheets({"title" => title, "title-exact" => "true"})[0] end |
#spreadsheet_by_url(url) ⇒ Object
Returns GoogleDriveV0::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")
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/google_drive_v0/session.rb', line 214 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) case uri.path when /\/d\/([^\/]+)/ return spreadsheet_by_key($1) when /\/ccc$/ if (uri.query || "").split(/&/).find(){ |s| s=~ /^key=(.*)$/ } return spreadsheet_by_key($1) end 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 GoogleDriveV0::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")
183 184 185 186 187 188 189 190 191 192 |
# File 'lib/google_drive_v0/session.rb', line 183 def spreadsheets(params = {}) url = concat_url( "#{DOCS_BASE_URL}/-/spreadsheet?v=3", "?" + encode_query(params)) doc = request(:get, url, :auth => :writely) # The API may return non-spreadsheets too when title-exact is specified. # Probably a bug. For workaround, only returns Spreadsheet instances. return doc.css("feed > entry"). map(){ |e| entry_element_to_file(e) }. select(){ |f| f.is_a?(Spreadsheet) } 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/csv")
354 355 356 357 358 359 360 |
# File 'lib/google_drive_v0/session.rb', line 354 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.
364 365 366 367 368 369 370 371 |
# File 'lib/google_drive_v0/session.rb', line 364 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"] entry = upload_raw(:post, initial_url, io, title, params) return entry_element_to_file(entry) 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")
332 333 334 |
# File 'lib/google_drive_v0/session.rb', line 332 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:
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 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 |
# File 'lib/google_drive_v0/session.rb', line 373 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;charset=utf-8", "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 doc.root end |
#worksheet_by_url(url) ⇒ Object
Returns GoogleDriveV0::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")
245 246 247 |
# File 'lib/google_drive_v0/session.rb', line 245 def worksheet_by_url(url) return Worksheet.new(self, nil, url) end |