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.



132
133
134
135
136
137
138
139
140
# File 'lib/gdocs4ruby/base_object.rb', line 132

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

Instance Attribute Details

#author_emailObject (readonly)

The author/owner email



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

def author_email
  @author_email
end

#author_nameObject (readonly)

The author/owner name



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

def author_name
  @author_name
end

#bytes_usedObject (readonly)

Quota bytes used by the document



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

def bytes_used
  @bytes_used
end

#content_uriObject (readonly)

The content uri for exporting the object content



123
124
125
# File 'lib/gdocs4ruby/base_object.rb', line 123

def content_uri
  @content_uri
end

#foldersObject (readonly)

An array of folders this object belongs to



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

def folders
  @folders
end

#html_uriObject (readonly)

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



120
121
122
# File 'lib/gdocs4ruby/base_object.rb', line 120

def html_uri
  @html_uri
end

#local_fileObject

A local file to upload content from



129
130
131
# File 'lib/gdocs4ruby/base_object.rb', line 129

def local_file
  @local_file
end

#publishedObject (readonly)

The raw date the document was published



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

def published
  @published
end

#typeObject (readonly)

The type of the object, one of TYPES



117
118
119
# File 'lib/gdocs4ruby/base_object.rb', line 117

def type
  @type
end

#updatedObject (readonly)

The raw date the document was last updated



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

def updated
  @updated
end

#viewedObject (readonly)

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



126
127
128
# File 'lib/gdocs4ruby/base_object.rb', line 126

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.

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)


329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/gdocs4ruby/base_object.rb', line 329

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 event 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 = []
    term = query.is_a?(Hash) ? CGI::escape(query[:query]) : CGI::escape(query)
    args["q"] = term if term and term != ''
    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

.get_instance(service, d) ⇒ Object



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
# File 'lib/gdocs4ruby/base_object.rb', line 368

def self.get_instance(service, d)
  if d.is_a? Net::HTTPOK
    xml = REXML::Document.new(d.read_body).root
    if xml.name == 'feed'
      xml = xml.elements.each("entry"){}[0]
    end
  else
    xml = d
  end
  ele = GData4Ruby::Utils::add_namespaces(xml)
  obj = BaseObject.new(service)
  obj.load(ele.to_s)
  case obj.type
    when 'document'
      doc = Document.new(service)
    when 'spreadsheet'
      doc = Spreadsheet.new(service)
    when 'folder'
      doc = Folder.new(service)
    when 'presentation'
      doc = Presentation.new(service)
  end
  doc.load(ele.to_s)
  doc
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.



212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/gdocs4ruby/base_object.rb', line 212

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.



229
230
231
232
233
234
# File 'lib/gdocs4ruby/base_object.rb', line 229

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)


356
357
358
359
# File 'lib/gdocs4ruby/base_object.rb', line 356

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.



180
181
182
# File 'lib/gdocs4ruby/base_object.rb', line 180

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.



185
186
187
# File 'lib/gdocs4ruby/base_object.rb', line 185

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.



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/gdocs4ruby/base_object.rb', line 284

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
  if not load(ret.read_body)
    raise SaveFailed
  end
  return ret
end

#load(string) ⇒ Object

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



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/gdocs4ruby/base_object.rb', line 144

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 'published'
        @published = ele.text
      when 'updated'
        @updated = ele.text
      when 'content'
        @content_uri = ele.attributes['src']
      when 'link'
        case ele.attributes['rel']
          when 'edit-media'
            @edit_content_uri = ele.attributes['href']
          when 'alternate'
            @html_uri = ele.attributes['href']
        end
      when 'author'
        ele.elements.each('name'){}.map {|e| @author_name = e.text}
        ele.elements.each('email'){}.map {|e| @author_email = e.text}
      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.



313
314
315
316
317
318
# File 'lib/gdocs4ruby/base_object.rb', line 313

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).



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

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)


362
363
364
365
# File 'lib/gdocs4ruby/base_object.rb', line 362

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.



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/gdocs4ruby/base_object.rb', line 190

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
    if not load(ret.read_body)
      raise SaveFailed
    end
    return true
  else
    return create
  end
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.



304
305
306
307
308
# File 'lib/gdocs4ruby/base_object.rb', line 304

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.



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

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