Ruby Technorati API Client

Published: 09 Dec 2007

So as part of a pet project I decided to write a Ruby client for the Technorati API. There are several available requests that can be made and each has it's own options to pass for things like the response format. I should mention there is also a Technorati-Ruby gem available that looks like it was written back in 2004 and weighs in at around 500 lines. Mine weighs in at 130 lines or so but doesn't provide a response parser.

# A Ruby client implementation of the Technorati API.
# Copyright 2007 Shane Witbeck, Digital Sanctum, Inc.
# Website: http://www.digitalsanctum.com

require 'net/http'

module Technorati

  protected

  class Api

    def execute
      url = get_url
      resp = Net::HTTP.get_response(URI.parse(url))
      resp.body
    end

    protected

    def init(key, context, options=nil)
      @key = key
      @context = context
      @options = options ||= {}
    end

    def get_url()
      base_url = "http://api.technorati.com"
      url = "#{base_url}/#{@context}?key=#{@key}"
      @options.each { |key,val| url << "&#{key}=#{val}" }
      url
    end

    def add_option(key, val)
      @options = @options.merge({key=>val}) unless (val.nil? || val == '')
    end
  end

  module TechnoratiFormat
    attr_reader :format
    def format=(format) add_option(:format, format) end
  end

  module TechnoratiCollection
    attr_reader :limit, :start
    def limit=(limit) add_option(:limit, limit) end
    def start=(start) add_option(:start, start) end
  end

  public

  class TopTags < Api
    include TechnoratiFormat
    include TechnoratiCollection
    def initialize(key, options=nil)
      init(key, "toptags", options)
    end
  end

  class Cosmos < Api
    include TechnoratiFormat
    include TechnoratiCollection
    attr_reader :url, :type, :current, :claim, :highlight
    def initialize(key, url, options={})
      init(key, "cosmos", options.merge({:url=>url}))
    end
    def url=(url) add_option(:url, url) end
    def type=(type) add_option(:type, type) end
    def current=(current) add_option(:current, current) end
    def claim=(claim) add_option(:claim, claim) end
    def highlight=(highlight) add_option(:highlight, highlight) end
  end

  class Search < Api
    include TechnoratiFormat
    include TechnoratiCollection
    attr_accessor :language, :authority
    def initialize(key, query, options={})
      init(key, "search", options.merge({:query=>query}))
    end
    def authority=(authority) add_option(:authority, authority) end
    def language=(language) add_option(:language, language) end
    def query=(query) add_option(:query, query) end
  end

  class Tag < Api
    include TechnoratiFormat
    include TechnoratiCollection
    attr_accessor :excerptsize, :topexcerptsize
    def initialize(key, tag, options={})
      init(key, "tag", options.merge({:tag=>tag}))
    end
    def excerptsize=(excerptsize) add_option(:excerptsize, excerptsize) end
    def topexcerptsize=(topexcerptsize) add_option(:topexcerptsize, topexcerptsize) end
    def tag=(tag) add_option(:tag, tag) end
  end

  class DailyCounts < Api
    include TechnoratiFormat
    attr_reader :days
    def initialize(key, q, options={})
      init(key, "dailycounts", options.merge({:q=>q}))
    end
    def days=(days) add_option(:days, days) end
    def q=(q) add_option(:q, q) end
  end

  class BlogInfo < Api
    include TechnoratiFormat
    def initialize(key, url, options={})
      init(key, "bloginfo", options.merge({:url=>url}))
    end
    def url=(url) add_option(:url, url) end
  end

  class BlogPostTags < Api
    attr_accessor :limit
    def initialize(key, url, options={})
      init(key, "blogposttags", options.merge({:url=>url}))
    end
    def limit=(limit) add_option(:limit, limit) end
    def url=(url) add_option(:url, url) end
  end

  class GetInfo < Api
    include TechnoratiFormat
    def initialize(key, username, options={})
      init(key, "getinfo", options.merge({:username=>username}))
    end
    def username=(username) add_option(:username, username) end
  end
end