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.
-
#find_by_id(resource_id) ⇒ Object
Returns GoogleDrive::File.
-
#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.
227 228 229 |
# File 'lib/google_drive/session.rb', line 227 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")
244 245 246 247 248 249 250 251 252 |
# File 'lib/google_drive/session.rb', line 244 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).
219 220 221 |
# File 'lib/google_drive/session.rb', line 219 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")
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/google_drive/session.rb', line 258 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:
399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
# File 'lib/google_drive/session.rb', line 399 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 |
#find_by_id(resource_id) ⇒ Object
Returns GoogleDrive::File. Returns nil if not found
136 137 138 139 |
# File 'lib/google_drive/session.rb', line 136 def find_by_id(resource_id) doc = request(:get, "https://docs.google.com/feeds/documents/private/full/#{resource_id}", :auth => :writely) return entry_element_to_file(doc) end |
#inspect ⇒ Object
445 446 447 |
# File 'lib/google_drive/session.rb', line 445 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:
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 |
# File 'lib/google_drive/session.rb', line 414 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.
214 215 216 |
# File 'lib/google_drive/session.rb', line 214 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")
167 168 169 170 |
# File 'lib/google_drive/session.rb', line 167 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.
198 199 200 |
# File 'lib/google_drive/session.rb', line 198 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")
182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/google_drive/session.rb', line 182 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")
148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/google_drive/session.rb', line 148 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/csv")
318 319 320 321 322 323 324 |
# File 'lib/google_drive/session.rb', line 318 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.
328 329 330 331 332 333 334 |
# File 'lib/google_drive/session.rb', line 328 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")
296 297 298 |
# File 'lib/google_drive/session.rb', line 296 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:
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 391 392 393 394 395 396 397 |
# File 'lib/google_drive/session.rb', line 336 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")
209 210 211 |
# File 'lib/google_drive/session.rb', line 209 def worksheet_by_url(url) return Worksheet.new(self, nil, url) end |