Ruby でも WebService::Simple みたいなことをしたい

Twitter に POST したり、Wassr に POST したり、はてなハイクに POST したり・・・をまとめようと思っていたら、WebService::Simple を知りました。

そんなわけで、WebService::Simple を Ruby 風のクラスベースにしてみました。
param や response_parser の実装などの機能強化はおいおい。

2009/06/03 追記 @@instance_values の保存方法が間違っていたのを修正。
そのうちどこかリボジトリに保存するかな。

メインソース

#!/usr/bin/ruby

require 'kconv'
require 'webapi'

class Wassr < WebAPI::Base
  basic_auth('めーるあどれす or ゆーざめい', 'ぱすわーど')
  base_url 'http://api.wassr.jp/statuses/'
end

w = Wassr.new
puts w.post('update.json', {:source => 'WebService::Simple(Ruby)', :status => "Ruby でも WebService::Simple したい".toutf8})

webapi.rb

#!/usr/bin/ruby

require 'net/http'
require 'uri'
require 'kconv'

Net::HTTP.version_1_2

module WebAPI
  class Base
    def initialize
      options = {}
      options = @@instance_values[self.class.to_s]  if @@instance_values.key?(self.class.to_s)

      options.each_pair do |k, v|
        send(k, *v)
      end
    end

    def base_url(url)
      @base_url = URI.parse(url)
    end

    def basic_auth(username, password)
      @username = username
      @password = password
    end

    def params(p)
      @params = p
    end

    def post(request_uri, params = {})
      p = @params.merge(params)

      Net::HTTP.start(@base_url.host, @base_url.port) do |http|
        req = Net::HTTP::Post.new(@base_url.request_uri + request_uri)
        req["user-agent"] = "Ruby/#{RUBY_VERSION}"

        req.basic_auth(@username, @password)  if @username && @password
        req.set_form_data(p)

        res = http.request(req)

        res.body.toutf8
      end
    end

    @@instance_values = {}
    METHODS = [:base_url, :basic_auth, :params]

    def self.method_missing(name, *args)
      return nil  unless METHODS.include?(name)

      @@instance_values[self.to_s] = {}  unless @@instance_values.key?(self.to_s)

      @@instance_values[self.to_s][name] = args
    end
  end
end