require "net/http" require "uri" require "rexml/document" require "time" module NTimeLine URL = URI.parse("http://api.timeline.nifty.com/api/v1") class Base attr_accessor :timeline_key, :updated # # setters # def self.text_data(*args) @text_data ? @text_data += args : @text_data = args attr_reader *args end def self.int_data(*args) @int_data ? @int_data += args : @int_data = args attr_reader *args end def self.bool_data(*args) @bool_data ? @bool_data += args : @bool_data = args attr_reader *args end def self.time_data(*args) @time_data ? @time_data += args : @time_data = args attr_reader *args end def self.url_data(*args) @url_data ? @url_data += args : @url_data = args attr_reader *args end # # methods # def initialize(res) #:nodoc: init(res) end def refresh(res) #:nodoc: init(res) return self end def init(res) #:nodoc: self.class.instance_eval{@text_data||[]}.each do |data| if res.elements[data.to_s] instance_variable_set("@"+data.to_s, res.elements[data.to_s].text) end end self.class.instance_eval{@int_data||[]}.each do |data| if res.elements[data.to_s] instance_variable_set("@"+data.to_s, res.elements[data.to_s].text.to_i) end end self.class.instance_eval{@bool_data||[]}.each do |data| if res.elements[data.to_s] instance_variable_set("@"+data.to_s, (res.elements[data.to_s].text == "true")) end end self.class.instance_eval{@time_data||[]}.each do |data| if res.elements[data.to_s] instance_variable_set("@"+data.to_s, Time.parse(res.elements[data.to_s].text)) end end self.class.instance_eval{@url_data||[]}.each do |data| if res.elements[data.to_s].text instance_variable_set("@"+data.to_s, URI.parse(res.elements[data.to_s].text)) end end end # Send a request message to the server. # path:: relative path from http://api.timeline.nifty.com/api/v1 # params:: parameters hash table # target:: class or object def self.request(path, params={}, target = self) req = Net::HTTP::Post.new(URL.path + path) data = params.inject(Hash.new) do |data, (key, val)| val.kind_of?(Time) ? data[key.to_s] = val.iso8601 : data[key.to_s] = val data end req.set_form_data data case res = Net::HTTP.new(URL.host).request(req) when Net::HTTPSuccess doc = REXML::Document.new(res.body) obj = target.kind_of?(Class) ? target.new(doc) : target.refresh(doc) obj.request_params = params if obj.kind_of?(NTimeLine::Pager) obj.timeline_key = params[:timeline_key] if params.has_key?(:timeline_key) return obj when Net::HTTPBadRequest raise BadRequestError.new(REXML::Document.new(res.body)) when Net::HTTPForbidden p res.body raise ForbiddenError.new(REXML::Document.new(res.body)) else raise ResponseError.new(res) end end # Same as request but need timeline_key. # path:: relative path from http://api.timeline.nifty.com/api/v1 # params:: parameters hash table # target:: class or object def self.request_with_key(path, params={}, target=self) # check timeline_key unless params.has_key?(:timeline_key) raise ArgumentError, "There is not :timeline_key in params" end # request request(path, params, target) end # Same as request. def request(path, params={}, target = self.class) self.class.request(path, params, target) end # Same as request_with_key. def request_with_key(path, params={}, target = self.class) self.class.request_with_key(path, params, target) end end # Succeeded is a dummy class for successful response. class Succeeded < Base def initialize(doc); end end # # EXCEPTIONS # class Error < StandardError; end class ResponseError < Error attr_reader :response def initialize(response) @response = response end end class BadRequestError < Error def initialize(res) @response = res @code = res.elements["/response/status/code"].text.to_i @message = res.elements["/response/status/message"].text end def message self.class.name + "(code:" + @code.to_s + "): message=" + @message end end end require 'ntimeline/article' require 'ntimeline/timeline' require 'ntimeline/pager' require 'ntimeline/user' require 'ntimeline/version'