require 'cgi' require 'net/http' require 'uri' require 'pyrosoma/frame' class URI::Generic public :path_query end class Pyrosoma class HTTP class ServerError < RuntimeError attr_reader :status, :reply def initialize(msg, status=nil, reply=nil) @status = status @reply = reply super msg end end def initialize(root) @root = root.chomp("/") end HEADER = {'Accept' => 'text/plain'} def GET(relpath) uri = URI(@root + relpath) Net::HTTP.start(uri.host, uri.port) { |http| http.request_get(uri.path_query, HEADER) { |response| return [response.code.to_i, response.body] } } end def POST(relpath, data) uri = URI(@root + relpath) Net::HTTP.start(uri.host, uri.port) { |http| post = Net::HTTP::Post.new(uri.path_query, HEADER) post.form_data = data http.request(post) { |response| return [response.code.to_i, response.body] } } end def get(id) status, reply = GET("/inspect/#{id}") case status when 200 frame = Frame.load reply frame.db = self frame else raise ServerError.new("couldn't retrieve #{id}: #{status}", status, reply) end end def post(frame) frame.db = self if frame.kind_of? Frame status, reply = POST("/", {'document' => frame.to_s}) case status when 200 reply else raise ServerError.new("couldn't store #{id}: #{status}", status, reply) end end def <<(frame) post frame self end def import(string) post frame=Frame.load(string) frame end def ids status, reply = GET("/list") case status when 200 reply.split("\n") else raise ServerError.new("couldn't retrieve ids: #{status}", status, reply) end end def size # XXX yuck ids.size end def search_each(query, &block) # XXX add options status, reply = GET("/list?query=" + CGI.escape(query)) case status when 200 results = reply.split("\n") results.each(&block) if block results else raise ServerError.new("couldn't search for #{query}: #{status}", status, reply) end end end end