class Atompub::Client

Atompub::Client

Attributes

agent[RW]

user agent

rc[R]

resource object for current networking context

req[R]

request object for current networking context

request[R]

request object for current networking context

res[R]

response object for current networking context

resource[R]

resource object for current networking context

response[R]

response object for current networking context

Public Class Methods

new(params={}) click to toggle source

Initializer

  • auth

  • cache

# File lib/atomutil.rb, line 1319
def initialize(params={})
  unless params.has_key?(:auth)
    throw ArgumentError.new("Atompub::Client needs :auth as argument for constructor.")
  end
  @auth  = params.has_key?(:auth) && params[:auth].kind_of?(Auth::Abstract) ? params[:auth] : Auth::Abstract.new
  @cache = params.has_key?(:cache) && params[:cache].kind_of?(AbstractCache) ? params[:cache] : AbstractCache.instance
  @service_info = params.has_key?(:info) && params[:info].kind_of?(ServiceInfoStorage) ? params[:info] : ServiceInfoStorage.instance
  @http_class = Net::HTTP
  @agent = "Atompub::Client/#{AtomUtil::VERSION}"
end

Public Instance Methods

create_entry(post_uri, entry, slug=nil) click to toggle source

Create new entry

Example:

entry = Atom::Entry.new
entry.title = 'foo'
author = Atom::Author.new
author.name = 'Lyo Kato'
author.email = 'lyo.kato@gmail.com'
entry.author = author
entry_uri = client.create_entry(post_uri, entry)
# File lib/atomutil.rb, line 1432
def create_entry(post_uri, entry, slug=nil)
  unless entry.kind_of?(Atom::Entry)
    entry = Atom::Entry.new :stream => entry
  end
  service = @service_info.get(post_uri)
  unless entry.categories.all?{ |c| service.allows_category?(c) }
    raise RequestError, "Forbidden Category"
  end
  create_resource(post_uri, entry.to_s, Atom::MediaType::ENTRY.to_s, slug)
  @res['Location']
end
create_media(media_uri, file_path, content_type, slug=nil) click to toggle source

Create new media resource

Example:

media_uri = client.create_media(post_media_uri, 'myimage.jpg', 'image/jpeg')
# File lib/atomutil.rb, line 1449
def create_media(media_uri, file_path, content_type, slug=nil)
  file_path = Pathname.new(file_path) unless file_path.is_a?(Pathname)
  stream = file_path.open { |f| f.binmode; f.read }
  service = @service_info.get(media_uri)
  if service.nil?
    raise RequestError, "Service information not found. Get service document before you do create_media."
  end
  unless service.accepts_media_type?(content_type)
    raise RequestError, "Unsupported Media Type: #{content_type}"
  end
  create_resource(media_uri, stream, content_type, slug)
  @res['Location']
end
delete_entry(edit_uri) click to toggle source

Delete entry

Example:

entry = client.get_entry(resource_uri)
client.delete_entry(entry.edit_link)
# File lib/atomutil.rb, line 1495
def delete_entry(edit_uri)
  delete_resource(edit_uri)
end
delete_media(media_uri) click to toggle source

Delete media

Example:

entry = client.get_entry(resource_uri)
client.delete_media(entry.edit_media_link)
# File lib/atomutil.rb, line 1505
def delete_media(media_uri)
  delete_resource(media_uri)
end
get_categories(categories_uri) click to toggle source

Get categories This returns Atom::Categories object. see the document of Atom::Categories in detail.

Example:

# File lib/atomutil.rb, line 1372
def get_categories(categories_uri)
  get_contents_except_resources(categories_uri) do |res|
    #warn "Bad Content Type" unless Atom::MediaType::CATEGORIES.is_a?(@res['Content-Type'])
    @rc = Atom::Categories.new :stream => @res.body
  end
  @rc
end
get_entry(entry_uri) click to toggle source

Get entry

Example:

entry = client.get_entry(entry_uri)
puts entry.id
puts entry.title
# File lib/atomutil.rb, line 1400
def get_entry(entry_uri)
  get_resource(entry_uri)
  unless @rc.instance_of?(Atom::Entry)
    raise ResponseError, "Response is not Atom Entry"
  end
  @rc
end
get_feed(feed_uri) click to toggle source

Get feed This returns Atom::Feed object. see the document of Atom::Feed in detail.

Example:

# File lib/atomutil.rb, line 1385
def get_feed(feed_uri)
  get_contents_except_resources(feed_uri) do |res|
    #warn "Bad Content Type" unless Atom::MediaType::FEED.is_a?(@res['Content-Type'])
    @rc = Atom::Feed.new :stream => res.body
  end
  @rc
end
get_media(media_uri) click to toggle source

Get media resource

Example:

resource, content_type = client.get_media(media_uri)
# File lib/atomutil.rb, line 1413
def get_media(media_uri)
  get_resource(media_uri)
  if @rc.instance_of?(Atom::Entry)
    raise ResponseError, "Response is not Media Resource"
  end
  return @rc, @res.content_type
end
get_service(service_uri) click to toggle source

Get service document This returns Atom::Service object. see the document of Atom::Service in detail.

Example:

service = client.get_service(service_uri)
service.workspaces.each do |w|
  w.collections.each do |c|
    puts c.href
  end
end
# File lib/atomutil.rb, line 1352
def get_service(service_uri)
  get_contents_except_resources(service_uri) do |res|
    #warn "Bad Content Type" unless Atom::MediaType::SERVICE.is_a?(@res['Content-Type'])
    @rc = Atom::Service.new :stream => @res.body
    @rc.workspaces.each do |workspace|
      workspace.collections.each do |collection|
        #@service_info.put(collection.href, collection, self)
        @service_info.put(collection.href, collection)
      end
    end
  end
  @rc
end
update_entry(edit_uri, entry) click to toggle source

Update entry

Example:

entry = client.get_entry(resource_uri)
entry.summary = "Changed Summary!"
client.update_entry(entry)
# File lib/atomutil.rb, line 1470
def update_entry(edit_uri, entry)
  unless entry.kind_of?(Atom::Entry)
    entry = Atom::Entry.new :stream => entry
  end
  update_resource(edit_uri, entry.to_s, Atom::MediaType::ENTRY.to_s)
end
update_media(media_uri, file_path, content_type) click to toggle source

Update media resource

Example:

entry = client.get_entry(media_link_uri)
client.update_media(entry.edit_media_link, 'newimage.jpg', 'image/jpeg')
# File lib/atomutil.rb, line 1483
def update_media(media_uri, file_path, content_type)
  file_path = Pathname.new(file_path) unless file_path.is_a?(Pathname)
  stream = file_path.open { |f| f.binmode; f.read }
  update_resource(media_uri, stream, content_type)
end
use_proxy(uri, port, user=nil, pass=nil) click to toggle source

Set proxy if you need.

Example:

client.use_proxy('http://myproxy/', 8080)
client.use_proxy('http://myproxy/', 8080, 'myusername', 'mypassword')
# File lib/atomutil.rb, line 1336
def use_proxy(uri, port, user=nil, pass=nil)
  @http_class = Net::HTTP::Proxy(uri, port, user, pass)
end

Private Instance Methods

clear() click to toggle source

clear objects which depend on each networking context.

# File lib/atomutil.rb, line 1648
def clear
  @req = nil
  @res = nil
  @rc  = nil
end
create_resource(uri, r, content_type, slug=nil) click to toggle source

Create new resources(entry or media)

# File lib/atomutil.rb, line 1566
def create_resource(uri, r, content_type, slug=nil)
  clear
  uri = URI.parse(uri)
  #service = @service_info.get(uri.to_s)
  #unless service.accepts_media_type(content_type)
  #  raise UnsupportedMediaTypeError, "Unsupported media type: #{content_type}."
  #end
  @req = Net::HTTP::Post.new uri.request_uri
  @req['Content-Type'] = content_type
  @req['Slug'] = URI.encode(URI.decode(slug)) unless slug.nil?
  set_common_info(@req)
  @req.body = r
  @http_class.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
    @res = http.request(@req)
    case @res
      when Net::HTTPSuccess
        #warn "Bad Status Code: #{@res.code}" unless @res.class == Net::HTTPCreated
        #warn "Bad Content Type: #{@res['Content-Type']}" unless Atom::MediaType::ENTRY.is_a?(@res['Content-Type'])
        if @res['Location'].nil?
          raise ResponseError, "No Location"
        end
        unless @res.body.nil?
          @rc = Atom::Entry.new :stream => @res.body
          @cache.put uri.to_s, {
            :rc            => @rc,
            :last_modified => @res['Last-Modified'],
            :etag          => @res['ETag']
          }
        end
      else
        error_message = @res.body.nil?? "#{@res.code}" : "#{@res.code} / #{@res.body}"
        raise RequestError, "Failed to create resource. #{error_message}"
    end
  end
end
delete_resource(uri) click to toggle source

Delete resources(entry or media)

# File lib/atomutil.rb, line 1632
def delete_resource(uri)
  clear
  uri = URI.parse(uri)
  @req = Net::HTTP::Delete.new uri.request_uri
  set_common_info(@req)
  @http_class.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
    @res = http.request(@req)
    case @res
      when Net::HTTPSuccess
        #warn "Bad Status Code: #{@res.code}" unless @res.class == Net::HTTPOK || @res.class == Net::HTTPNoContent
      else
        raise RequestError, "Failed to delete resource. #{@res.code}"
      end
  end
end
get_contents_except_resources(uri, &block) click to toggle source

Get contents, for example, service-document, categories, and feed.

# File lib/atomutil.rb, line 1515
def get_contents_except_resources(uri, &block)
  clear
  uri = URI.parse(uri)
  @req = Net::HTTP::Get.new uri.request_uri
  set_common_info(@req)
  @http_class.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
    @res = http.request(@req)
    case @res
      when Net::HTTPOK
        block.call(@res) if block_given?
      else
        raise RequestError, "Failed to get contents. #{@res.code}"
    end
  end
end
get_resource(uri) click to toggle source

Get resouces(entry or media)

# File lib/atomutil.rb, line 1531
def get_resource(uri)
  clear
  uri = URI.parse(uri)
  @req = Net::HTTP::Get.new uri.request_uri
  set_common_info(@req)
  cache = @cache.get(uri.to_s)
  unless cache.nil?
    @req['If-Modified-Since'] = cache.last_modified unless cache.last_modified.nil?
    @req['If-None-Match'] = cache.etag unless cache.etag.nil?
  end
  @http_class.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
    @res = http.request(@req)
    case @res
      when Net::HTTPOK
        if Atom::MediaType::ENTRY.is_a?(@res['Content-Type'])
          @rc = Atom::Entry.new :stream => @res.body
        else
          @rc = @res.body
        end
        @cache.put uri.to_s, {
          :rc            => @rc,
          :last_modified => @res['Last-Modified'],
          :etag          => @res['ETag'] }
      when Net::HTTPNotModified
        unless cache.nil?
          @rc = cache.rc
        else
          raise CacheNotFoundError, "Got Not-Modified response, but has no cache."
        end
      else
        raise RequestError, "Failed to get content. #{@res.code}"
    end
  end
end
set_common_info(req) click to toggle source

Set request headers those are required on each request accessing resources.

# File lib/atomutil.rb, line 1510
def set_common_info(req)
  req['User-Agent'] = @agent
  @auth.authorize(req)
end
update_resource(uri, r, content_type) click to toggle source

updated resources(entry or media)

# File lib/atomutil.rb, line 1602
def update_resource(uri, r, content_type)
  clear
  uri = URI.parse(uri)
  @req = Net::HTTP::Put.new uri.request_uri
  @req['Content-Type'] = content_type
  cache = @cache.get(uri.to_s)
  unless cache.nil?
    @req['If-Not-Modified-Since'] = cache.last_modofied unless cache.last_modified.nil?
    @req['If-Match'] = cache.etag unless cache.etag.nil?
  end
  set_common_info(@req)
  @req.body = r
  @http_class.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
    @res = http.request(@req)
    case @res
      when Net::HTTPSuccess
        #warn "Bad Status Code: #{@res.code}" unless @res.class == Net::HTTPOK || @res.class == Net::HTTPNoContent
        unless @res.body.nil?
          @rc = Atom::MediaType::ENTRY.is_a?(@res['Content-Type']) ? Atom::Entry.new(:stream => @res.body) : @res.body
          @cache.put uri.to_s, {
            :rc            => @rc,
            :etag          => @res['ETag'],
            :last_modified => @res['Last-Modified'] }
        end
      else
        raise RequestError, "Failed to update resource. #{@res.code}"
    end
  end
end