Class: GoogleDrive::File

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/google_drive/file.rb

Overview

A file in Google Drive, including Google Docs document/spreadsheet/presentation.

Use GoogleDrive::Session#files or GoogleDrive::Session#file_by_title to get this object.

Direct Known Subclasses

Collection, Spreadsheet

Constant Summary

Constants included from Util

Util::DOCS_BASE_URL, Util::EXT_TO_CONTENT_TYPE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util

concat_url, encode_query, h, to_v3_url

Constructor Details

#initialize(session, entry_or_url) ⇒ File

:nodoc:



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/google_drive/file.rb', line 21

def initialize(session, entry_or_url) #:nodoc:
  @session = session
  if !entry_or_url
    # TODO Delete this after editing spreadsheet.rb.
    @document_feed_entry = nil
    @document_feed_url = entry_or_url
  elsif entry_or_url.is_a?(String)
    @document_feed_entry = nil
    @document_feed_url = entry_or_url
  else
    @document_feed_entry = entry_or_url
    # This is usually equal to the URL in <link rel="self">. But the URL in
    # <link rel="self"> in collection feed is e.g.
    # https://docs.google.com/feeds/default/private/full/folder%3Aroot/contents/folder%3Axxx
    # and deletion of the URL doesn't delete the file itself.
    # So we construct the URL here using resource ID instead.
    @document_feed_url = "%s/%s?v=3" % [DOCS_BASE_URL, CGI.escape(self.resource_id)]
  end
  @acl = nil
end

Instance Attribute Details

#document_feed_urlObject (readonly)

URL of feed used in document list feed API.



43
44
45
# File 'lib/google_drive/file.rb', line 43

def document_feed_url
  @document_feed_url
end

Instance Method Details

#acl(params = {}) ⇒ Object

Returns GoogleDrive::Acl object for the file.

With the object, you can see and modify people who can access the file. Modifications take effect immediately.

Set params[:reload] to true to force reloading the data.

e.g.

# Dumps people who have access:
for entry in file.acl
  p [entry.scope_type, entry.scope, entry.role]
  # => e.g. ["user", "[email protected]", "owner"]
end

# Shares the file with new people:
# NOTE: This sends email to the new people.
file.acl.push(
    {:scope_type => "user", :scope => "[email protected]", :role => "reader"})
file.acl.push(
    {:scope_type => "user", :scope => "[email protected]", :role => "writer"})

# Changes the role of a person:
file.acl[1].role = "writer"

# Deletes an ACL entry:
file.acl.delete(file.acl[1])


243
244
245
246
247
248
# File 'lib/google_drive/file.rb', line 243

def acl(params = {})
  if !@acl || params[:reload]
    @acl = Acl.new(@session, self.acl_feed_url)
  end
  return @acl
end

#acl_feed_urlObject

ACL feed URL of the file.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/google_drive/file.rb', line 88

def acl_feed_url
  orig_acl_feed_url = self.document_feed_entry_internal.css(
      "gd|feedLink[rel='http://schemas.google.com/acl/2007#accessControlList']")[0]["href"]
  case orig_acl_feed_url
    when %r{^https?://docs.google.com/feeds/default/private/full/.*/acl(\?.*)?$}
      return orig_acl_feed_url
    when %r{^https?://docs.google.com/feeds/acl/private/full/([^\?]*)(\?.*)?$}
      # URL of old API version. Converts to v3 URL.
      return "#{DOCS_BASE_URL}/#{$1}/acl"
    else
      raise(GoogleDrive::Error,
        "ACL feed URL is in unknown format: #{orig_acl_feed_url}")
  end
end

#available_content_typesObject

Content types you can specify in methods download_to_file, download_to_string, download_to_io .



105
106
107
# File 'lib/google_drive/file.rb', line 105

def available_content_types
  return self.document_feed_entry_internal.css("content").map(){ |c| c["type"] }
end

#delete(permanent = false) ⇒ Object

If permanent is false, moves the file to the trash. If permanent is true, deletes the file permanently.



194
195
196
197
198
199
# File 'lib/google_drive/file.rb', line 194

def delete(permanent = false)
  url = to_v3_url(self.document_feed_url)
  url = concat_url(url, "?delete=true") if permanent
  @session.request(:delete, url,
    :auth => :writely, :header => {"If-Match" => "*"})
end

#document_feed_entry(params = {}) ⇒ Object

<entry> element of document list feed as Nokogiri::XML::Element.

Set params[:reload] to true to force reloading the feed.



48
49
50
51
52
53
# File 'lib/google_drive/file.rb', line 48

def document_feed_entry(params = {})
  warn(
      "WARNING: GoogleDrive::file\#document_feed_entry is deprecated and will be removed " +
      "in the next version.")
  return self.document_feed_entry_internal(params)
end

#document_feed_entry_internal(params = {}) ⇒ Object

:nodoc:



55
56
57
58
59
60
61
# File 'lib/google_drive/file.rb', line 55

def document_feed_entry_internal(params = {}) #:nodoc:
  if !@document_feed_entry || params[:reload]
    @document_feed_entry =
        @session.request(:get, self.document_feed_url, :auth => :writely).css("entry")[0]
  end
  return @document_feed_entry
end

#download_to_file(path, params = {}) ⇒ Object

Downloads the file to a local file.

e.g.

file.download_to_file("/path/to/hoge.txt")
file.download_to_file("/path/to/hoge", :content_type => "text/plain")


114
115
116
117
118
119
120
121
122
123
# File 'lib/google_drive/file.rb', line 114

def download_to_file(path, params = {})
  params = params.dup()
  if !params[:content_type]
    params[:content_type] = EXT_TO_CONTENT_TYPE[::File.extname(path).downcase]
    params[:content_type_is_hint] = true
  end
  open(path, "wb") do |f|
    download_to_io(f, params)
  end
end

#download_to_io(io, params = {}) ⇒ Object

Downloads the file and writes it to io.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/google_drive/file.rb', line 137

def download_to_io(io, params = {})
  all_contents = self.document_feed_entry_internal.css("content")
  if params[:content_type] && (!params[:content_type_is_hint] || all_contents.size > 1)
    contents = all_contents.select(){ |c| c["type"] == params[:content_type] }
  else
    contents = all_contents
  end
  if contents.size == 1
    url = contents[0]["src"]
  else
    if contents.empty?
      raise(GoogleDrive::Error,
          ("Downloading with content type %p not supported for this file. " +
           "Specify one of these to content_type: %p") %
          [params[:content_type], self.available_content_types])
    else
      raise(GoogleDrive::Error,
          ("Multiple content types are available for this file. " +
           "Specify one of these to content_type: %p") %
          [self.available_content_types])
    end
  end
  # TODO Use streaming if possible.
  body = @session.request(:get, url, :response_type => :raw, :auth => :writely)
  io.write(body)
end

#download_to_string(params = {}) ⇒ Object

Downloads the file and returns as a String.

e.g.

file.download_to_string()                               #=> "Hello world."
file.download_to_string(:content_type => "text/plain")  #=> "Hello world."


130
131
132
133
134
# File 'lib/google_drive/file.rb', line 130

def download_to_string(params = {})
  sio = StringIO.new()
  download_to_io(sio, params)
  return sio.string
end

#human_urlObject

URL to view/edit the file in a Web browser.

e.g. “docs.google.com/file/d/xxxx/edit



83
84
85
# File 'lib/google_drive/file.rb', line 83

def human_url
  return self.document_feed_entry_internal.css("link[rel='alternate']")[0]["href"]
end

#inspectObject



250
251
252
253
254
# File 'lib/google_drive/file.rb', line 250

def inspect
  fields = {:document_feed_url => self.document_feed_url}
  fields[:title] = self.title if @document_feed_entry
  return "\#<%p %s>" % [self.class, fields.map(){ |k, v| "%s=%p" % [k, v] }.join(", ")]
end

#rename(title) ⇒ Object Also known as: title=

Renames title of the file.



202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/google_drive/file.rb', line 202

def rename(title)
  edit_url = self.document_feed_entry_internal.css("link[rel='edit']").first["href"]
  xml = <<-"EOS"
    <atom:entry
        xmlns:atom="http://www.w3.org/2005/Atom"
        xmlns:docs="http://schemas.google.com/docs/2007">
      <atom:title>#{h(title)}</atom:title>
    </atom:entry>
  EOS
  header = {"Content-Type" => "application/atom+xml;charset=utf-8", "If-Match" => "*"}
  @session.request(:put, edit_url, :data => xml, :auth => :writely, :header => header)
end

#resource_idObject

Resource ID.



64
65
66
# File 'lib/google_drive/file.rb', line 64

def resource_id
  return self.document_feed_entry_internal.css("gd|resourceId").text
end

#resource_typeObject

The type of resourse. e.g. “document”, “spreadsheet”, “folder”



69
70
71
# File 'lib/google_drive/file.rb', line 69

def resource_type
  return self.resource_id.split(/:/)[0]
end

#title(params = {}) ⇒ Object

Title of the file.

Set params[:reload] to true to force reloading the title.



76
77
78
# File 'lib/google_drive/file.rb', line 76

def title(params = {})
  return document_feed_entry_internal(params).css("title").text
end

#update_from_file(path, params = {}) ⇒ Object

Updates the file with the content of the local file.

e.g.

file.update_from_file("/path/to/hoge.txt")


168
169
170
171
172
173
# File 'lib/google_drive/file.rb', line 168

def update_from_file(path, params = {})
  params = {:file_name => ::File.basename(path)}.merge(params)
  open(path, "rb") do |f|
    update_from_io(f, params)
  end
end

#update_from_io(io, params = {}) ⇒ Object

Reads content from io and updates the file with the content.



184
185
186
187
188
189
190
# File 'lib/google_drive/file.rb', line 184

def update_from_io(io, params = {})
  params = {:header => {"If-Match" => "*"}}.merge(params)
  initial_url = self.document_feed_entry_internal.css(
      "link[rel='http://schemas.google.com/g/2005#resumable-edit-media']")[0]["href"]
  @document_feed_entry = @session.upload_raw(
      :put, initial_url, io, self.title, params)
end

#update_from_string(content, params = {}) ⇒ Object

Updates the file with content.

e.g.

file.update_from_string("Good bye, world.")


179
180
181
# File 'lib/google_drive/file.rb', line 179

def update_from_string(content, params = {})
  update_from_io(StringIO.new(content), params)
end