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(access_token, proxy = nil) ⇒ 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
titleas 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
mailandpassword, 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
titleandcontent. -
#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.
70 71 72 73 74 75 76 |
# File 'lib/google_drive/session.rb', line 70 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.
114 115 116 |
# File 'lib/google_drive/session.rb', line 114 def on_auth_fail @on_auth_fail end |
Class Method Details
.login(mail, password, proxy = nil) ⇒ Object
The same as GoogleDrive.login.
36 37 38 39 40 |
# File 'lib/google_drive/session.rb', line 36 def self.login(mail, password, proxy = nil) 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 GoogleDrive.login_with_oauth.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/google_drive/session.rb', line 43 def self.login_with_oauth(access_token, proxy = nil) case access_token when OAuth::AccessToken raise(GoogleDrive::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(GoogleDrive::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 GoogleDrive::Session object for testing.
65 66 67 |
# File 'lib/google_drive/session.rb', line 65 def self.new_dummy() return Session.new(nil, Object.new()) end |
.restore_session(auth_tokens, proxy = nil) ⇒ Object
The same as GoogleDrive.restore_session.
60 61 62 |
# File 'lib/google_drive/session.rb', line 60 def self.restore_session(auth_tokens, proxy = nil) return Session.new(auth_tokens, nil, proxy) end |
Instance Method Details
#auth_token(auth = :wise) ⇒ Object
Authentication token.
108 109 110 |
# File 'lib/google_drive/session.rb', line 108 def auth_token(auth = :wise) return self.auth_tokens[auth] end |
#auth_tokens ⇒ Object
Authentication tokens.
98 99 100 101 102 103 104 105 |
# File 'lib/google_drive/session.rb', line 98 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.
232 233 234 |
# File 'lib/google_drive/session.rb', line 232 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")
249 250 251 252 253 254 255 256 257 |
# File 'lib/google_drive/session.rb', line 249 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).
224 225 226 |
# File 'lib/google_drive/session.rb', line 224 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")
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/google_drive/session.rb', line 263 def create_spreadsheet( title = "Untitled", feed_url = "https://docs.google.com/feeds/documents/private/full") xml = " <atom:entry\n xmlns:atom=\"http://www.w3.org/2005/Atom\"\n xmlns:docs=\"http://schemas.google.com/docs/2007\">\n <atom:category\n scheme=\"http://schemas.google.com/g/2005#kind\"\n term=\"http://schemas.google.com/docs/2007#spreadsheet\"\n label=\"spreadsheet\"/>\n <atom:title>\#{h(title)}</atom:title>\n </atom:entry>\n EOS\n\n doc = request(:post, feed_url, :data => xml, :auth => :writely)\n ss_url = doc.css(\n \"link[rel='http://schemas.google.com/spreadsheets/2006#worksheetsfeed']\")[0][\"href\"]\n return Spreadsheet.new(self, ss_url, title)\n \nend\n" |
#entry_element_to_file(entry) ⇒ Object
:nodoc:
404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/google_drive/session.rb', line 404 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.
If given an Array, traverses collections by title. e.g.
session.file_by_title(["myfolder", "mysubfolder/even/w/slash", "myfile"])
138 139 140 141 142 143 144 |
# File 'lib/google_drive/session.rb', line 138 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 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")
125 126 127 128 129 130 |
# File 'lib/google_drive/session.rb', line 125 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
450 451 452 |
# File 'lib/google_drive/session.rb', line 450 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.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/google_drive/session.rb', line 81 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.message}") end end |
#request(method, url, params = {}) ⇒ Object
:nodoc:
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 444 445 446 447 448 |
# File 'lib/google_drive/session.rb', line 419 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.
219 220 221 |
# File 'lib/google_drive/session.rb', line 219 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")
172 173 174 175 |
# File 'lib/google_drive/session.rb', line 172 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.
203 204 205 |
# File 'lib/google_drive/session.rb', line 203 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")
187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/google_drive/session.rb', line 187 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")
153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/google_drive/session.rb', line 153 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")
323 324 325 326 327 328 329 |
# File 'lib/google_drive/session.rb', line 323 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.
333 334 335 336 337 338 339 |
# File 'lib/google_drive/session.rb', line 333 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")
301 302 303 |
# File 'lib/google_drive/session.rb', line 301 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:
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 398 399 400 401 402 |
# File 'lib/google_drive/session.rb', line 341 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 = " <entry xmlns=\"http://www.w3.org/2005/Atom\" \n xmlns:docs=\"http://schemas.google.com/docs/2007\">\n <title>\#{h(title)}</title>\n </entry>\n EOS\n \n default_initial_header = {\n \"Content-Type\" => \"application/atom+xml\",\n \"X-Upload-Content-Type\" => content_type,\n \"X-Upload-Content-Length\" => total_bytes.to_s(),\n }\n initial_full_url = concat_url(url, params[:convert] ? \"?convert=true\" : \"?convert=false\")\n initial_response = request(method, initial_full_url,\n :header => default_initial_header.merge(params[:header] || {}),\n :data => initial_xml,\n :auth => :writely,\n :response_type => :response)\n upload_url = initial_response[\"location\"]\n \n if total_bytes > 0\n sent_bytes = 0\n while data = io.read(UPLOAD_CHUNK_SIZE)\n content_range = \"bytes %d-%d/%d\" % [\n sent_bytes,\n sent_bytes + data.bytesize - 1,\n total_bytes,\n ]\n upload_header = {\n \"Content-Type\" => content_type,\n \"Content-Range\" => content_range,\n }\n doc = request(\n :put, upload_url, :header => upload_header, :data => data, :auth => :writely)\n sent_bytes += data.bytesize\n end\n else\n upload_header = {\n \"Content-Type\" => content_type,\n }\n doc = request(\n :put, upload_url, :header => upload_header, :data => \"\", :auth => :writely)\n end\n \n return entry_element_to_file(doc.root)\n \nend\n" |
#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")
214 215 216 |
# File 'lib/google_drive/session.rb', line 214 def worksheet_by_url(url) return Worksheet.new(self, nil, url) end |