Class: GDocs4Ruby::BaseObject

Inherits:
GData4Ruby::GDataObject
  • Object
show all
Defined in:
lib/gdocs4ruby/base_object.rb

Overview

The base object class that includes all major methods for interacting with Google Documents API.

Usage

All usages assume you’ve already authenticated with the service, and have a service object called Note: You probably don’t want to instantiate a BaseObject directly, but rather use any of the subclasses Document, Spreadsheet, and Presentation

  1. Create a new Document doc = BaseObject.new(@service) doc.title = ‘Test Document’ doc.content = ‘<h1>Test Content HTML</h1>’ doc.content_type = ‘html’ doc.save

  2. Deleting a Document doc = BaseObject.find(@service, => @doc_id) doc.delete

  3. Finding an existing Document by id doc = BaseObject.find(@service, => @doc_id)

  4. Full Text Query doc = BaseObject.find(@service, ‘content text’)

or

 doc = BaseObject.find(@service, {:query => 'content text'})
  1. Finding an Existing Document by Title doc = BaseObject.find(@service, nil, ‘any’, => ‘Test Document’)

  2. Updating a Document with Content from a Local File doc = BaseObject.find(@service, => @doc_id) doc.title = ‘New Title’ doc.local_file = ‘/path/to/some/file’ doc.save

Direct Known Subclasses

Document, Folder

Constant Summary collapse

ENTRY_XML =
'<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
  <atom:title></atom:title>
</atom:entry>'
BOUNDARY =
'GDOCS4RUBY_BOUNDARY'
UPLOAD_TYPES =
{'' => 'text/txt',
:csv => 'text/csv', 
:tsv => 'text/tab-separated-values', 
:tab => 'text/tab-separated-values',
:html => 'text/html',
:htm => 'text/html',
:doc => 'application/msword',
:docx => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
:ods => 'application/x-vnd.oasis.opendocument.spreadsheet',
:odt => 'application/vnd.oasis.opendocument.text',
:rtf => 'application/rtf',
:sxw => 'application/vnd.sun.xml.writer',
:txt => 'text/plain',
:xls => 'application/vnd.ms-excel',
:xlsx => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
:pdf => 'application/pdf',
:ppt => 'application/vnd.ms-powerpoint',
:pps => 'application/vnd.ms-powerpoint',
:pptx => 'application/vnd.ms-powerpoint'}
FEEDS =
{:document => "https://docs.google.com/feeds/documents/private/full/",
:folder => "http://docs.google.com/feeds/folders/private/full/",
:spreadsheet => "https://docs.google.com/feeds/documents/private/full/",
:presentation => "https://docs.google.com/feeds/documents/private/full/",
:any => "https://docs.google.com/feeds/documents/private/full/"}
QUERY_FEEDS =
{:document => "https://docs.google.com/feeds/documents/private/full/-/document",
:folder => "http://docs.google.com/feeds/folders/private/full/?showfolders=true",
:spreadsheet => "https://docs.google.com/feeds/documents/private/full/-/spreadsheet",
:presentation => "https://docs.google.com/feeds/documents/private/full/-/presentation",
:any => "https://docs.google.com/feeds/documents/private/full/"}
TYPES =
["document", "folder", "spreadsheet", "presentation", "any"]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(service, attributes = {}) ⇒ BaseObject

Creates a new BaseObject instance. Requires a valid GData4Ruby::Service object.



117
118
119
120
121
122
123
124
# File 'lib/gdocs4ruby/base_object.rb', line 117

def initialize(service, attributes = {})
  super(service, attributes)
  @xml = ENTRY_XML
  @folders = []
  @edit_content_uri = nil
  @viewed = false
  @content = @content_type = nil
end

Instance Attribute Details

#bytes_usedObject (readonly)

Quota bytes used by the document



102
103
104
# File 'lib/gdocs4ruby/base_object.rb', line 102

def bytes_used
  @bytes_used
end

#foldersObject (readonly)

An array of folders this object belongs to



99
100
101
# File 'lib/gdocs4ruby/base_object.rb', line 99

def folders
  @folders
end

#html_uriObject (readonly)

The uri for the html editor of the object (the web editor for documents)



108
109
110
# File 'lib/gdocs4ruby/base_object.rb', line 108

def html_uri
  @html_uri
end

#local_fileObject

A local file to upload content from



114
115
116
# File 'lib/gdocs4ruby/base_object.rb', line 114

def local_file
  @local_file
end

#typeObject (readonly)

The type of the object, one of TYPES



105
106
107
# File 'lib/gdocs4ruby/base_object.rb', line 105

def type
  @type
end

#viewedObject (readonly)

Flag indicating whether the document has the ‘viewed’ category link.



111
112
113
# File 'lib/gdocs4ruby/base_object.rb', line 111

def viewed
  @viewed
end

Class Method Details

.find(service, query, type = 'any', args = {}) ⇒ Object

Finds a BaseObject based on a text query or by an id. Parameters are:

service

A valid Service object to search.

query

either a string containing a text query to search by, or a hash containing an id key with an associated id to find, or a query key containint a text query to search for, or a title key containing a title to search.

type

used to limit results to a specific document type, as list in TYPES.

args

a hash containing optional additional query paramters to use. See code.google.com/apis/gdata/docs/2.0/reference.html#Queries for a full list of possible values. Example:

=> ‘100’ If an ID is specified, a single instance of the document is returned if found, otherwise false. If a query term is specified, and array of matching results is returned, or an empty array if nothing was found.

Raises:

  • (ArgumentError)


301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/gdocs4ruby/base_object.rb', line 301

def self.find(service, query, type = 'any', args = {})      
  raise ArgumentError, 'query must be a hash or string' if not query.is_a? Hash and not query.is_a? String
  raise ArgumentError, "type must be one of #{TYPES.join(" ")}" if not TYPES.include? type
  if query.is_a? Hash and query[:id]
    id = query[:id]
    puts "id passed, finding document by id" if service.debug
    puts "id = "+id if service.debug
    d = service.send_request(GData4Ruby::Request.new(:get, FEEDS[type.to_sym]+id, {"If-Not-Match" => "*"}))
    puts d.inspect if service.debug
    if d
      return get_instance(service, d)
    end
  else
    results = []
    if query.is_a?(Hash)
      args["q"] = query[:query] if query[:query]
      args['title'] = query[:title] if query[:title]
    else
      args["q"] = CGI::escape(query) if query != ''
    end
    ret = service.send_request(GData4Ruby::Request.new(:get, QUERY_FEEDS[type.to_sym], nil, nil, args))
    xml = REXML::Document.new(ret.body).root
    xml.elements.each("entry") do |e|
      results << get_instance(service, e)
    end
    return results
  end
  return false
end

Instance Method Details

#access_rulesObject

Retrieves an array of GData4Ruby::AccessRules representing the access rules for the object, as contained in the Google ACL.



187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/gdocs4ruby/base_object.rb', line 187

def access_rules
  rules = []
  ret = service.send_request(GData4Ruby::Request.new(:get, @acl_uri))
  xml = REXML::Document.new(ret.read_body).root
  xml.elements.each("entry") do |e|
    ele = GData4Ruby::Utils::add_namespaces(e)
    rule = GData4Ruby::ACL::AccessRule.new(service, self)
    puts ele.to_s if service.debug
    rule.load(ele.to_s)
    rules << rule
  end
  rules
end

#add_access_rule(user, role) ⇒ Object

Adds a new access rule for the object. Parameters are:

user

the user (email address) to add permissions for

role

can be one of ‘viewer’ or ‘writer’ depending on whether the user should be able to edit or read only.



204
205
206
207
208
209
# File 'lib/gdocs4ruby/base_object.rb', line 204

def add_access_rule(user, role)
  a = GData4Ruby::ACL::AccessRule.new(service, self)
  a.user = user
  a.role = role
  a.save
end

#add_to_folder(folder) ⇒ Object

Adds the object to the specified folder. The parameter must be a valid Folder object.

Raises:

  • (ArgumentError)


332
333
334
335
# File 'lib/gdocs4ruby/base_object.rb', line 332

def add_to_folder(folder)
  raise ArgumentError, 'folder must be a GDocs4Ruby::Folder' if not folder.is_a? Folder
  @service.send_request(GData4Ruby::Request.new(:post, folder.content_uri, to_xml))
end

#content=(value) ⇒ Object

Sets content to save to the document. Content must be formatted as one of the types in UPLOAD_TYPES.



155
156
157
# File 'lib/gdocs4ruby/base_object.rb', line 155

def content=(value)
  @content = value
end

#content_type=(value) ⇒ Object

Sets the content_type stored in content. content_type must be one of the keys in UPLOAD_TYPES.



160
161
162
# File 'lib/gdocs4ruby/base_object.rb', line 160

def content_type=(value)
  @content_type = value
end

#createObject

Creates a new object instance on the Google server if the object doesn’t already exist.



259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/gdocs4ruby/base_object.rb', line 259

def create
  ret = if (not @local_file.nil? and @local_file.is_a? String) or @content
    if @local_file
      service.send_request(GData4Ruby::Request.new(:post, DOCUMENT_LIST_FEED, create_multipart_message([{:type => 'application/atom+xml', :content => to_xml()}, {:type => UPLOAD_TYPES[File.extname(@local_file).gsub(".", "").to_sym], :content => get_file(@local_file).read}]), {'Content-Type' => "multipart/related; boundary=#{BOUNDARY}", 'Content-Length' => File.size(@local_file).to_s, 'Slug' => File.basename(@local_file)}))
    elsif @content
      service.send_request(GData4Ruby::Request.new(:post, DOCUMENT_LIST_FEED, create_multipart_message([{:type => 'application/atom+xml', :content => to_xml()}, {:type => UPLOAD_TYPES[@content_type.to_sym], :content => @content}]), {'Content-Type' => "multipart/related; boundary=#{BOUNDARY}", 'Content-Length' => @content.size.to_s, 'Slug' => @title}))
    end      
  else
    service.send_request(GData4Ruby::Request.new(:post, DOCUMENT_LIST_FEED, to_xml()))
  end
  return ret
end

#load(string) ⇒ Object

Loads a string containing an XML <entry> from a Google API feed.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/gdocs4ruby/base_object.rb', line 128

def load(string)
  super(string)
  @folders = []
  xml = REXML::Document.new(string)
  xml.root.elements.each(){}.map do |ele|
    @etag = xml.root.attributes['etag'] if xml.root.attributes['etag']
    case ele.name
      when 'link'
        case ele.attributes['rel']
          when 'edit-media'
            @edit_content_uri = ele.attributes['href']
          when 'alternate'
            @html_uri = ele.attributes['href']
        end
      when 'quotaBytesUsed'
        @bytes_used = ele.text
    end
  end
  @categories.each do |cat|
    @folders << cat[:label] if cat[:scheme] and cat[:scheme].include? "folders"
    @viewed = true if cat[:label] and cat[:label] == 'viewed'
    @type = cat[:label] if cat[:scheme] and cat[:scheme] == 'http://schemas.google.com/g/2005#kind'
  end
  return xml.root
end

#put_content(content, type = 'text/html') ⇒ Object

Saves arbitrary content to the object. Parameters must be:

content

the content to upload. Content should be formatted as one of the UPLOAD_TYPES.

type

an optional paramter specifying the type, if not HTML. This value must be a mime-type enumerated in UPLOAD_TYPES.



285
286
287
288
289
290
# File 'lib/gdocs4ruby/base_object.rb', line 285

def put_content(content, type = 'text/html')
  ret = service.send_request(GData4Ruby::Request.new(:put, @edit_content_uri, content, {'Content-Type' => type, 
                                             'Content-Length' => content.length.to_s,
                                             'If-Match' => "*"}))
  load(ret.body)
end

#remove_access_rule(user) ⇒ Object

Removes an access rule for the specified user. Parameter should be a valid user Id (email address).



248
249
250
251
252
253
254
255
256
# File 'lib/gdocs4ruby/base_object.rb', line 248

def remove_access_rule(user)
  a = GData4Ruby::ACL::AccessRule.find(service, self, {:user => user})
  if a
    if a.delete
      return true
    end
  end
  return false
end

#remove_from_folder(folder) ⇒ Object

Removes the object from the specified folder. The parameter must be a valid Folder object.

Raises:

  • (ArgumentError)


338
339
340
341
# File 'lib/gdocs4ruby/base_object.rb', line 338

def remove_from_folder(folder)
  raise ArgumentError, 'folder must be a GDocs4Ruby::Folder' if not folder.is_a? Folder
  @service.send_request(GData4Ruby::Request.new(:delete, folder.content_uri+"/"+CGI::escape(id), nil, {"If-Match" => "*"}))
end

#saveObject

Saves or creates the object depending on whether it exists or not.



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/gdocs4ruby/base_object.rb', line 165

def save
  if @exists
    if (not @local_file.nil? and @local_file.is_a? String) or @content
      @include_etag = false
      if @local_file
        ret = service.send_request(GData4Ruby::Request.new(:put, @edit_content_uri, create_multipart_message([{:type => 'application/atom+xml', :content => to_xml()}, {:type => UPLOAD_TYPES[File.extname(@local_file).gsub(".", "").to_sym], :content => get_file(@local_file).read}]), {'Content-Type' => "multipart/related; boundary=#{BOUNDARY}", 'Content-Length' => File.size(@local_file).to_s, 'Slug' => File.basename(@local_file), 'If-Match' => "*"}))
      elsif @content
        ret = service.send_request(GData4Ruby::Request.new(:put, @edit_content_uri, create_multipart_message([{:type => 'application/atom+xml', :content => to_xml()}, {:type => UPLOAD_TYPES[@content_type.to_sym], :content => @content}]), {'Content-Type' => "multipart/related; boundary=#{BOUNDARY}", 'Content-Length' => @content.size.to_s, 'Slug' => @title, 'If-Match' => "*"}))
      end
    else
      ret = service.send_request(GData4Ruby::Request.new(:put, @edit_uri, to_xml()))
    end
  else
    ret = create
  end
  if not load(ret.read_body)
    raise SaveFailed
  end
  return true
end

#to_iframe(options = {}) ⇒ Object

Returns a simple iframe containing the html_uri link for the document.

Note: you must either be logged in to Google as the owner of the document for this to work, or have appropriate read/write permissions set up on the document.



276
277
278
279
280
# File 'lib/gdocs4ruby/base_object.rb', line 276

def to_iframe(options = {})
  width = options[:width] || '800'
  height = options[:height] || '500'
  return "<iframe height='#{height}' width='#{width}' src='#{@html_uri}'></iframe>"
end

#update_access_rule(user, role) ⇒ Object

Updates an existing access rule for the object. Parameters are:

user

the user (email address) to update permissions

role

can be one of ‘viewer’ or ‘writer’ depending on whether the user should be able to edit or read only.



236
237
238
239
240
241
242
243
244
245
# File 'lib/gdocs4ruby/base_object.rb', line 236

def update_access_rule(user, role)
  a = GData4Ruby::ACL::AccessRule.find(service, self, {:user => user})
  if a
    a.role = role
    if a.save
      return true
    end
  end
  return false
end